diff --git a/src/app.ts b/src/app.ts
index b09c7a6031e06391a8012c00273e54a5f1c2babb..e6d5770c86cecf1b08c301dab08272ec2b385a68 100644
--- a/src/app.ts
+++ b/src/app.ts
@@ -11,13 +11,13 @@ import helmet from 'helmet'
 import compression from 'compression'
 import methodOverride from 'method-override'
 
-const env = process.env.NODE_ENV || 'development'
+const env = process.env.NODE_ENV ?? 'testing'
 const config = require('./config/config')[env]
 const lang = 'DE'
 
 const app = express()
 app.set('port', config.app.port)
-app.set('views', path.join(__dirname + '/views'))
+app.set('views', path.join(path.join(__dirname, '/views')))
 app.set('view engine', 'pug')
 
 // enable files upload
diff --git a/src/classes/project.ts b/src/classes/project.ts
index 325713c1fb3a87ee620f0253dcfa10b987f52b65..e6ad4d8990a07cb50fbe75da5d075cfc89fcecdf 100644
--- a/src/classes/project.ts
+++ b/src/classes/project.ts
@@ -66,4 +66,4 @@ class Project {
   }
 }
 
-export = Project
+export { Project }
diff --git a/src/classes/repo.ts b/src/classes/repo.ts
index c8c6db93581d922608d0666fe386b46b1b5246e7..e35a8fb72e6a71676ad58c0d5546e23814285937 100644
--- a/src/classes/repo.ts
+++ b/src/classes/repo.ts
@@ -1,4 +1,4 @@
-import Project from './project'
+import { Project } from './project'
 
 class Repo extends Project {
   constructor (ownerGitlabId: number, name: string, desc: string, id?: number, logo?: string, path?: string) {
@@ -6,4 +6,4 @@ class Repo extends Project {
   }
 }
 
-export = Repo
+export { Repo }
diff --git a/src/classes/user.ts b/src/classes/user.ts
index d25196f91f05d1acf4b34b9fa356f73165c3e527..554e248fed55aeafc2cc894b9ecaa1438f9b85ac 100644
--- a/src/classes/user.ts
+++ b/src/classes/user.ts
@@ -8,12 +8,12 @@ class User {
   industry: string
   organisation: string
   speciality: string
-  is_m4lab_idp: number // 1 or 0
+  isM4labIdp: number // 1 or 0
   verificationStatus: number // 1 or 0 - // should be boolean
   gitlabUserId?: number
 
   constructor (id: number, email: string, salutation: string, title: string, firstName: string, lastName: string, industry: string, organisation: string,
-    speciality: string, is_m4lab_idp: number, verificationStatus: number, gitlabUserId?: number) {
+    speciality: string, isM4labIdp: number, verificationStatus: number, gitlabUserId?: number) {
     this.id = id
     this.email = email
     this.salutation = salutation
@@ -23,7 +23,7 @@ class User {
     this.industry = industry
     this.organisation = organisation
     this.speciality = speciality
-    this.is_m4lab_idp = is_m4lab_idp
+    this.isM4labIdp = isM4labIdp
     this.verificationStatus = verificationStatus
     this.gitlabUserId = gitlabUserId
   }
@@ -42,7 +42,7 @@ class User {
   }
 
   getIdpStatus () {
-    return this.is_m4lab_idp
+    return this.isM4labIdp
   }
 
   getVerificationStatus () {
@@ -86,8 +86,8 @@ class User {
     this.speciality = speciality
   }
 
-  setM4lab_idp (m4lab_idp: number) {
-    this.is_m4lab_idp = m4lab_idp
+  setM4lab_idp (m4labIdp: number) {
+    this.isM4labIdp = m4labIdp
   }
 
   setVerificationStatus (verificationStatus: number) {
@@ -110,4 +110,4 @@ class User {
   }
 }
 
-export = User
+export { User }
diff --git a/src/classes/website.ts b/src/classes/website.ts
index 0cd6f0026e71658140c2d09af9b4d322450d978e..6a07f9287c31ec80319e63070bfde8e8bec8dd7c 100644
--- a/src/classes/website.ts
+++ b/src/classes/website.ts
@@ -1,4 +1,4 @@
-import Project from './project'
+import { Project } from './project'
 
 class Website extends Project {
   constructor (ownerGitlabId: number, name: string, desc: string, id?: number, logo?: string, path?: string) {
@@ -6,4 +6,4 @@ class Website extends Project {
   }
 }
 
-export = Website
+export { Website }
diff --git a/src/config/config.ts b/src/config/config.ts
index 71a1454f77a74670c2728984cd4daaa1fc726eb3..623d558a93e263af1d97eb73ee6802e0364a7dbe 100644
--- a/src/config/config.ts
+++ b/src/config/config.ts
@@ -1,15 +1,15 @@
-export = {
+module.exports = {
   development: {
     app: {
       name: 'User Account Management',
-      port: process.env.PORT || 9989,
+      port: process.env.PORT ?? 9989,
       host: 'http://localhost:9989',
       sessionSecret: 'thisisasecret'
     },
     passport: {
       strategy: 'saml',
       saml: {
-        path: process.env.SAML_PATH || '/saml/SSO',
+        path: process.env.SAML_PATH ?? '/saml/SSO',
         entryPoint: process.env.SAML_ENTRY_POINT || 'saml entry point',
         issuer: 'SAML issuer',
         logoutUrl: 'SAML logout URL'
@@ -41,15 +41,15 @@ export = {
   testing: {
     app: {
       name: 'User Account Management',
-      port: process.env.PORT || 9989,
+      port: process.env.PORT ?? 9989,
       host: 'https://m4lab.hft-stuttgart.de/account',
       sessionSecret: 'thisisasecret'
     },
     passport: {
       strategy: 'saml',
       saml: {
-        path: process.env.SAML_PATH || '/saml/SSO',
-        entryPoint: process.env.SAML_ENTRY_POINT || 'saml entry point',
+        path: process.env.SAML_PATH ?? '/saml/SSO',
+        entryPoint: process.env.SAML_ENTRY_POINT ?? 'saml entry point',
         issuer: 'SAML issuer', // testing metadata
         logoutUrl: 'SAML logout URL'
       }
@@ -78,3 +78,5 @@ export = {
     }
   }
 }
+
+export {}
diff --git a/src/config/const.ts b/src/config/const.ts
index b8d625aa42a2a3375945f960fd1039a3e148d2dc..191275b7662068438c4f8c9698bc3ebe3c89770c 100644
--- a/src/config/const.ts
+++ b/src/config/const.ts
@@ -1,10 +1,10 @@
-export = {
+const miscConst = {
 
   mailSignature: 'Mit den besten Grüßen,<br/>das Transferportal-Team der HFT Stuttgart<br/><br/>' +
         'Transferportal der Hochschule für Technik Stuttgart<br/>' +
         'Schellingstr. 24   70174 Stuttgart<br/>' +
         'm4lab@hft-stuttgart.de<br/>' +
-        '<a href="https://transfer.hft-stuttgart.de">https://transfer.hft-stuttgart.de</a><br/>' +
+        '<a mailConsthref="https://transfer.hft-stuttgart.de">https://transfer.hft-stuttgart.de</a><br/>' +
         '<a href="http://www.hft-stuttgart.de/Aktuell/"><img border="0" alt="HFT" src="https://m4lab.hft-stuttgart.de/img/signature/hft_logo.png" width="30" height="30"></a>  &nbsp;' +
         '<a href="http://www.facebook.com/hftstuttgart"><img border="0" alt="Facebook" src="https://m4lab.hft-stuttgart.de/img/signature/fb_bw.png" width="30" height="30"></a>  &nbsp;' +
         '<a href="https://www.instagram.com/hft_stuttgart/"><img border="0" alt="Instagram" src="https://m4lab.hft-stuttgart.de/img/signature/instagram_bw.png" width="30" height="30"></a>  &nbsp;' +
@@ -17,3 +17,5 @@ export = {
   updatePasswordMailContent: '<div>Lieber Nutzer,<br/><br/>Ihr Passwort wurde erfolgreich geändert.<br/><br/></div>'
 
 }
+
+export { miscConst }
diff --git a/src/config/dbconn.ts b/src/config/dbconn.ts
index ee10a38313c580c4476af38d050e757e9e9aca46..2b0caa6d3f2952e0710123f594c49ee8e707da08 100644
--- a/src/config/dbconn.ts
+++ b/src/config/dbconn.ts
@@ -1,6 +1,6 @@
 import mysql from 'mysql2'
 
-const env = process.env.NODE_ENV || 'development'
+const env = process.env.NODE_ENV ?? 'development'
 const config = require('./config')[env]
 
 // ==== USER ACOOUNT DB CONNECTION ====
@@ -31,9 +31,9 @@ const projectConnection = mysql.createPool({
 
 projectConnection.query('USE ' + config.database.dbProject)
 
-const connection = {
+const dbConnection = {
   user: userConnection,
   project: projectConnection
 }
 
-export = connection
+export { dbConnection }
diff --git a/src/config/mailer.ts b/src/config/mailer.ts
index 1c528ae0e9b8979a912f79ce6767c99e77bc4a89..1b88cf93c85d0536d593d15566c07464f896d70b 100644
--- a/src/config/mailer.ts
+++ b/src/config/mailer.ts
@@ -1,7 +1,7 @@
 const nodemailer = require('nodemailer')
 const nodemailerNTLMAuth = require('nodemailer-ntlm-auth')
 
-const env = process.env.NODE_ENV || 'testing'
+const env = process.env.NODE_ENV ?? 'testing'
 const config = require('./config')[env]
 
 const smtpTransporter = nodemailer.createTransport({
@@ -37,4 +37,4 @@ const mailer: any = {
   options: mailOptions
 }
 
-export = mailer
+export { mailer }
diff --git a/src/controller/accountController.ts b/src/controller/accountController.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/controller/dbController.ts b/src/controller/dbController.ts
index 2162f10cc21797442ba260032d1d667949410387..12905c073fa58f461be602c190199436264a4f63 100644
--- a/src/controller/dbController.ts
+++ b/src/controller/dbController.ts
@@ -1,9 +1,9 @@
-import dbconn = require('../config/dbconn')
+import { dbConnection } from '../config/dbconn'
 
 const dbController = {
   // ===================== user db =====================
   registerNewUser: function (data: any, callback: any) {
-    dbconn.user.getConnection(function (err: any, thisconn) {
+    dbConnection.user.getConnection(function (err: any, thisconn) {
       thisconn.beginTransaction(function (err: any) { // START TRANSACTION
         if (err) { throw err }
         // insert profile
@@ -66,7 +66,7 @@ const dbController = {
   },
   getUserByEmail: async function (email: any) {
     try {
-      const rows: any = await dbconn.user.promise().query('SELECT id, verificationStatus, salutation, title, firstname, lastname, industry, organisation, speciality, m4lab_idp FROM user WHERE email = "' + email + '"')
+      const rows: any = await dbConnection.user.promise().query('SELECT id, verificationStatus, salutation, title, firstname, lastname, industry, organisation, speciality, m4lab_idp FROM user WHERE email = "' + email + '"')
       if (rows[0][0]) {
         return rows[0][0]
       } else { return null }
@@ -77,7 +77,7 @@ const dbController = {
   },
   getUserEmailById: async function (userId: number) {
     try {
-      const rows: any = await dbconn.user.promise().query('SELECT email FROM user WHERE id = ' + userId)
+      const rows: any = await dbConnection.user.promise().query('SELECT email FROM user WHERE id = ' + userId)
       if (rows[0][0]) {
         return rows[0][0].email
       } else { return null }
@@ -88,7 +88,7 @@ const dbController = {
   },
   checkUserEmail: async function (email: any) {
     try {
-      const rows: any = await dbconn.user.promise().query('SELECT id, email FROM user WHERE email = "' + email + '"')
+      const rows: any = await dbConnection.user.promise().query('SELECT id, email FROM user WHERE email = "' + email + '"')
       if (rows[0][0]) {
         return rows[0][0]
       } else { return null }
@@ -99,7 +99,7 @@ const dbController = {
   },
   getUserByToken: async function (token: any) {
     try {
-      const rows: any = await dbconn.user.promise().query('SELECT t1.user_id, t2.email FROM userdb.credential AS t1 INNER JOIN userdb.user AS t2 ON t1.user_id = t2.id AND t1.resetPasswordToken = "' +
+      const rows: any = await dbConnection.user.promise().query('SELECT t1.user_id, t2.email FROM userdb.credential AS t1 INNER JOIN userdb.user AS t2 ON t1.user_id = t2.id AND t1.resetPasswordToken = "' +
                 token + '" and resetPasswordExpires > ' + Date.now())
       if (rows[0][0]) {
         return rows[0][0]
@@ -111,7 +111,7 @@ const dbController = {
   },
   updateUserById: async function (userId: number, userData: any) {
     try {
-      const result: any = await dbconn.user.promise().query('UPDATE user SET ? WHERE id = ' + userId, userData)
+      const result: any = await dbConnection.user.promise().query('UPDATE user SET ? WHERE id = ' + userId, userData)
       return result
     } catch (err) {
       console.error(err)
@@ -120,7 +120,7 @@ const dbController = {
   },
   updateCredential: async function (data: any) {
     try {
-      const result: any = await dbconn.user.promise().query('UPDATE credential SET ? WHERE user_id = ' + data.user_id, data)
+      const result: any = await dbConnection.user.promise().query('UPDATE credential SET ? WHERE user_id = ' + data.user_id, data)
       return result
     } catch (err) {
       console.error(err)
@@ -128,14 +128,14 @@ const dbController = {
     return null
   },
   addUserProjectRole_OBSOLETE: function (data: any, callback: any) {
-    dbconn.user.query('INSERT INTO user_project_role SET ?', data, function (err: any) {
+    dbConnection.user.query('INSERT INTO user_project_role SET ?', data, function (err: any) {
       if (err) throw err
       callback(err)
     })
   },
   getVerificationTokenByUserId: async function (userId: number) {
     try {
-      const rows: any = await dbconn.user.promise().query('SELECT token FROM verification WHERE user_id = "' + userId + '"')
+      const rows: any = await dbConnection.user.promise().query('SELECT token FROM verification WHERE user_id = "' + userId + '"')
       if (rows[0][0]) {
         return rows[0][0].token
       } else { return null }
@@ -146,7 +146,7 @@ const dbController = {
   },
   getUserIdByVerificationToken: async function (token: any) {
     try {
-      const rows: any = await dbconn.user.promise().query('SELECT user_id FROM verification WHERE token = "' + token + '"')
+      const rows: any = await dbConnection.user.promise().query('SELECT user_id FROM verification WHERE token = "' + token + '"')
       if (rows[0][0]) {
         return rows[0][0].user_id
       } else {
@@ -158,7 +158,7 @@ const dbController = {
     return null
   },
   verifyUserAccount: function (userData: any, callback: any) {
-    dbconn.user.getConnection(function (err: any, thisconn) {
+    dbConnection.user.getConnection(function (err: any, thisconn) {
       thisconn.beginTransaction(function (err: any) { // START TRANSACTION
         if (err) { throw err }
         // update user status
@@ -186,7 +186,7 @@ const dbController = {
   /* ===== GitLab ===== */
   getGitlabId: async function (userId: number) {
     try {
-      const rows: any = await dbconn.user.promise().query('SELECT gu.gitlab_userId FROM user_gitlab gu, user u WHERE u.id = "' + userId + '" and gu.user_id = u.id')
+      const rows: any = await dbConnection.user.promise().query('SELECT gu.gitlab_userId FROM user_gitlab gu, user u WHERE u.id = "' + userId + '" and gu.user_id = u.id')
       if (rows[0][0]) {
         return rows[0][0].gitlab_userId
       } else {
@@ -198,7 +198,7 @@ const dbController = {
     }
   },
   addGitlabUser: function (data: any, callback: any) {
-    dbconn.user.query('INSERT INTO user_gitlab SET ?', data, function (err: any) {
+    dbConnection.user.query('INSERT INTO user_gitlab SET ?', data, function (err: any) {
       if (err) throw err
       callback(err)
     })
diff --git a/src/controller/gitlabController.ts b/src/controller/gitlabController.ts
index 647f2a4f0cfd56089ddc25378866bcd51bb54b0c..583a6a5d73d50b0a58c3d6e50c798a7c449c943a 100644
--- a/src/controller/gitlabController.ts
+++ b/src/controller/gitlabController.ts
@@ -2,7 +2,7 @@ import axios from 'axios'
 import fs from 'fs'
 import formData from 'form-data'
 
-const env = process.env.NODE_ENV || 'testing'
+const env = process.env.NODE_ENV ?? 'testing'
 const config = require('../config/config')[env]
 
 const gitlabController = {
@@ -124,4 +124,4 @@ const gitlabController = {
   }
 }
 
-export {gitlabController}
+export { gitlabController }
diff --git a/src/controller/publicController.ts b/src/controller/publicController.ts
index fa52e672eb603bf1228e097c691c2b746dcbc396..0035aee9c5843d61e40b8d459abf17316651753f 100644
--- a/src/controller/publicController.ts
+++ b/src/controller/publicController.ts
@@ -1,24 +1,26 @@
 import async from 'async'
-import mailer from '../config/mailer'
+import bcrypt from 'bcryptjs'
+import { mailer } from '../config/mailer'
+import { miscConst } from '../config/const'
 import { dbController } from './dbController'
 
-const lang = 'DE'
+const saltRounds: number = 10
 
 const publicController = {
-  showRegistrationPage: function (res: any) {
+  showRegistrationPage: function (res: any, lang: String) {
     res.render(lang + '/account/registration')
   },
-  showContactPage: function (req: any, res: any) {
+  showContactPage: function (req: any, res: any, lang: String) {
     res.render(lang + '/account/contact', {
       user: req.user
     })
   },
-  showForgotPwdPage: function (req: any, res: any) {
+  showForgotPwdPage: function (req: any, res: any, lang: String) {
     res.render(lang + '/account/forgotPwd', {
       user: req.user
     })
   },
-  showResetToken: async function (req: any, res: any) {
+  showResetPassword: async function (req: any, res: any, lang: String) {
     const user = await dbController.getUserByToken(req.params.token)
     if (user) {
       res.render(lang + '/account/reset')
@@ -53,6 +55,221 @@ const publicController = {
       res.redirect('/account/contact')
     })
   },
+  registerUser: function (req: any, res: any, config: any) {
+    // user data
+    const curDate: Date = new Date()
+    const userData: any = {
+      salutation: req.body.inputSalutation,
+      title: req.body.inputTitle,
+      firstname: req.body.inputFirstname,
+      lastname: req.body.inputLastname,
+      email: req.body.inputEmail,
+      organisation: req.body.inputOrganisation,
+      industry: req.body.inputIndustry,
+      speciality: req.body.inputSpeciality,
+      createdDate: curDate.toISOString().slice(0, 10)
+    }
+
+    const userEmail: any = userData.email
+    const pos: number = userEmail.indexOf('@')
+    const emailLength: number = userEmail.length
+    const emailDomain: any = userEmail.slice(pos, emailLength)
+
+    if (emailDomain.toLowerCase() === '@hft-stuttgart.de') {
+      res.flash('error', 'Fehlgeschlagen: HFT-Account')
+      res.redirect('/account/registration')
+    } else {
+      async.waterfall([
+        function (done: any) {
+          // generate token
+          let token: string = ''
+          const randomChars: string = 'abcdefghijklmnopqrstuvwxyz0123456789'
+          for (let i = 0; i < 40; i++) {
+            token += randomChars.charAt(Math.floor(Math.random() * randomChars.length))
+          }
+          // encrypt password
+          bcrypt.genSalt(saltRounds, function (err, salt) {
+            bcrypt.hash(req.body.inputPassword, salt, function (err: any, hash: any) {
+              const newAccount: any = {
+                profile: userData,
+                password: hash,
+                verificationToken: token
+              }
+              done(err, newAccount)
+            })
+          })
+        },
+        // save data
+        function (newAccount: any, err: any) {
+          dbController.registerNewUser(newAccount, function (err: any) {
+            if (err) {
+              res.flash('error', 'Fehlgeschlagen')
+            } else {
+              // send email
+              const emailSubject = 'Bitte bestätigen Sie Ihr M4_LAB Benutzerkonto'
+              const emailContent = '<div>Lieber Nutzer,<br/><br/>' +
+                '<p>vielen Dank für Ihre Anmeldung am Transferportal der HFT Stuttgart. <br/>' +
+                'Um Ihre Anmeldung zu bestätigen, klicken Sie bitte <a href=' + String(config.app.host) + '/verifyAccount?token=' + String(newAccount.verificationToken) + '>diesen Link</a> ' +
+                '<br/><br/>' +
+                'Ohne Bestätigung Ihres Kontos müssen wir Ihr Konto leider nach 7 Tagen löschen.</p><br/>' + String(miscConst.mailSignature) +
+                '</div>'
+              mailer.options.to = req.body.inputEmail
+              mailer.options.subject = emailSubject
+              mailer.options.html = emailContent
+              mailer.transporter.sendMail(mailer.options, function (err: any) {
+                if (err) {
+                  console.error('Cannot send email. [Error] ' + String(err))
+                  throw err
+                }
+              })
+              // user feedback
+              res.flash('success', 'Vielen Dank für Ihre Registrierung!' + '\r\n\r\n' +
+                'Wir haben Ihnen eine E-Mail an Ihre verwendete Adresse gesendet. Diese enthält einen Link zur Bestätigung Ihres Accounts.' + '\r\n' +
+                'Wenn Sie die Mail nicht in ihrem Postfach vorfinden, prüfen Sie bitte auch Ihren Spam-Ordner.')
+            }
+            res.redirect('/account/registration')
+          })
+        }
+      ])
+    }
+  },
+  verifyAccount: async function (req: any, res: any, lang: String) {
+    const userId: number = await dbController.getUserIdByVerificationToken(req.query.token)
+    if (!userId) {
+      // no user found
+      res.render(lang + '/account/verification', {
+        status: null
+      })
+    } else {
+      // a user found, verify the account
+      const userData: any = {
+        id: userId,
+        verificationStatus: 1
+      }
+      dbController.verifyUserAccount(userData, async function (err: any) {
+        if (err) {
+          console.error(err)
+          res.render(lang + '/account/verification', {
+            status: false
+          })
+        } else {
+          // send welcome email after successful account verification
+          const userEmail: string = await dbController.getUserEmailById(userId)
+          if (!userEmail) {
+            res.render(lang + '/account/verification', {
+              status: false
+            })
+          } else {
+            // send email
+            const emailSubject = 'Herzlich willkommen'
+            const emailContent = '<div>Lieber Nutzer,<br/><br/>' +
+              '<p>herzlich willkommen beim Transferportal der HFT Stuttgart!<br/>' +
+              'Sie können nun alle Dienste des Portals nutzen.<p/><br/>' + miscConst.mailSignature
+            mailer.options.to = userEmail
+            mailer.options.subject = emailSubject
+            mailer.options.html = emailContent
+            mailer.transporter.sendMail(mailer.options, function (err: any) {
+              if (err) {
+                console.log('cannot send email')
+                throw err
+              }
+            })
+
+            res.render(lang + '/account/verification', {
+              status: true
+            })
+          }
+        }
+      })
+    }
+  },
+  resetPassword: async function (req: any, res: any) {
+    const newPwd = req.body.inputNewPwd
+
+    const user = await dbController.getUserByToken(req.params.token)
+    if (!user) {
+      res.flash('error', 'User not found.')
+      res.redirect('/login')
+    } else {
+      // encrypt password
+      bcrypt.genSalt(saltRounds, function (err, salt) {
+        bcrypt.hash(newPwd, salt, async function (err: any, hash) {
+          const credentialData = {
+            password: hash,
+            user_id: user.user_id,
+            resetPasswordToken: null,
+            resetPasswordExpires: null
+          }
+          // update password
+          const result = await dbController.updateCredential(credentialData)
+          if (!result) {
+            console.log('Failed to reset password')
+            res.flash('error', 'Datenbankfehler: Passwort kann nicht geändert werden.')
+          } else {
+            res.flash('success', 'Passwort aktualisiert!')
+            // send notification email
+            mailer.options.to = user.email
+            mailer.options.subject = miscConst.updatePasswordMailSubject
+            mailer.options.html = miscConst.updatePasswordMailContent + '<div>' + miscConst.mailSignature + '</div>'
+            mailer.transporter.sendMail(mailer.options, function (err: any) {
+              if (err) { console.log(err) }
+            })
+          }
+          res.redirect('/login')
+        })
+      })
+    }
+  },
+  generateNewToken: function (req: any, res: any, config: any) {
+    const emailAddress = req.body.inputEmail
+    async.waterfall([
+      async function (done: any) {
+        const user = await dbController.checkUserEmail(emailAddress)
+        if (!user) {
+          console.log('No user found: ' + String(emailAddress))
+        } else {
+          // generate token
+          let token: string = ''
+          const randomChars: string = 'abcdefghijklmnopqrstuvwxyz0123456789'
+          for (let i = 0; i < 40; i++) {
+            token += randomChars.charAt(Math.floor(Math.random() * randomChars.length))
+          }
+
+          const emailSubject = 'Ihre Passwort-Anfrage an das Transferportal der HFT Stuttgart'
+          const emailContent = '<div>Lieber Nutzer,<br/><br/>' +
+            '<p>wir haben Ihre Anfrage zur Erneuerung Ihres Passwortes erhalten. Falls Sie diese Anfrage nicht gesendet haben, ignorieren Sie bitte diese E-Mail.<br/><br/>' +
+            'Sie können Ihr Passwort mit dem Klick auf diesen Link ändern: ' + String(config.app.host) + '/reset/' + String(token) + '<br/>' +
+            'Dieser Link ist aus Sicherheitsgründen nur für 1 Stunde gültig.<br/></p>' + String(miscConst.mailSignature) + '</div>'
+
+          const credentialData = {
+            user_id: user.id,
+            resetPasswordToken: token,
+            resetPasswordExpires: Date.now() + 3600000 // 1 hour
+          }
+          const result = await dbController.updateCredential(credentialData)
+          if (!result) {
+            console.log('failed to update credential')
+          } else {
+            // send email
+            mailer.options.to = emailAddress
+            mailer.options.subject = emailSubject
+            mailer.options.html = emailContent
+            mailer.transporter.sendMail(mailer.options, function (err: any) {
+              if (err) { console.error(err) }
+            })
+          }
+        }
+        done(null)
+      }
+    ], function (err: any) {
+      if (err) {
+        res.flash('error', 'Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.')
+      } else {
+        res.flash('success', 'Wenn Ihre E-Mail-Adresse registriert ist, wurde eine E-Mail mit dem weiteren Vorgehen an ' + String(emailAddress) + ' versendet.')
+      }
+      res.redirect('/account/forgotPwd')
+    })
+  },
   checkUserEmail: async function (req: any, res: any) {
     const user = await dbController.checkUserEmail(req.params.email)
     if (user) { res.send(false) } else {
diff --git a/src/functions/helpers_TBD.ts b/src/functions/helpers_TBD.ts
deleted file mode 100644
index 89506026042e8fb2b886a2a974fa3356d7a25c33..0000000000000000000000000000000000000000
--- a/src/functions/helpers_TBD.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-const helpers = {
-  stringToArray: function (input: string) {
-    if (input != null) {
-      return input.split(',')
-    } else {
-      return null
-    }
-  }
-}
-
-export = helpers
diff --git a/src/public/js/security.js b/src/public/js/security.js
index 672131647b9a46fe1661ce9171cb7dda0507f444..5d71fb8a7af81fa5f0f168d8e6df2101bf224dae 100644
--- a/src/public/js/security.js
+++ b/src/public/js/security.js
@@ -11,7 +11,7 @@ $('#inputNewPwd, #inputConfirm').on('keyup', function () {
   }
 
   // match or not?
-  if ($('#inputNewPwd').val() == $('#inputConfirm').val()) {
+  if ($('#inputNewPwd').val() === $('#inputConfirm').val()) {
     // $('#message').html('Matching').css('color', 'green');
     $('#message').html('Übereinstimmend').css('color', 'green')
     isMatch = true
diff --git a/src/routes/account.ts b/src/routes/account.ts
index 78a5699a55e6e8c9fe85d0a7caf84db93d86df23..e99095ac1de929df22940be54cffe3e2579c6212 100644
--- a/src/routes/account.ts
+++ b/src/routes/account.ts
@@ -2,14 +2,14 @@ import fs from 'fs'
 import async from 'async'
 import bcrypt from 'bcryptjs'
 import * as passportSaml from 'passport-saml'
-import dbconn from '../config/dbconn'
+import { dbConnection } from '../config/dbconn'
 import { dbController } from '../controller/dbController'
 import { gitlabController } from '../controller/gitlabController'
-import constants from '../config/const'
-import mailer from '../config/mailer'
-import portalUser from '../classes/user'
-import projectInformation from '../classes/website'
-import projectRepo from '../classes/repo'
+import { miscConst } from '../config/const'
+import { mailer } from '../config/mailer'
+import { User } from '../classes/user'
+import { Website } from '../classes/website'
+import { Repo } from '../classes/repo'
 
 const SamlStrategy = passportSaml.Strategy
 const saltRounds = 10
@@ -17,7 +17,7 @@ const salt = 64 // salt length
 const logoDir = 'public/upload/'
 const defaultLogo: any = 'public/default/logo.png'
 
-export = function (app: any, config: any, passport: any, lang: string) {
+module.exports = function (app: any, config: any, passport: any, lang: string) {
   // =========== PASSPORT =======
   passport.serializeUser(function (user: any, done: any) {
     done(null, user)
@@ -88,7 +88,7 @@ export = function (app: any, config: any, passport: any, lang: string) {
       console.log('no user found')
       return null
     } else {
-      const loggedInUser = new portalUser(
+      const loggedInUser = new User(
         user.id, email, user.salutation, user.title, user.firstname, user.lastname, user.industry, user.organisation, user.speciality, user.m4lab_idp, user.verificationStatus
       )
 
@@ -180,27 +180,23 @@ export = function (app: any, config: any, passport: any, lang: string) {
 
           if (loggedInUser.getGitlabUserId()) { // for users who have activated their gitlab account
             const userProjects = await gitlabController.getUserProjects(loggedInUser.getGitlabUserId()!)
-            if (!userProjects) {
-              console.error('something went wrong')
-              res.status(500).render(lang + '/500', { error: 'something went wrong' })
-            }
-
-            let project: any
-            for (project in userProjects) {
-              if (userProjects[project].tag_list.includes('website')) {
-                const page = {
-                  projectInformation: new projectInformation(loggedInUser.getGitlabUserId()!, userProjects[project].name, userProjects[project].description,
-                    userProjects[project].id, userProjects[project].avatar_url, userProjects[project].path_with_namespace),
-                  pipelineStatus: await gitlabController.getProjectPipelineLatestStatus(userProjects[project].id)
+            if (userProjects) {
+              let project: any
+              for (project in userProjects) {
+                if (userProjects[project].tag_list.includes('website')) {
+                  const page = {
+                    projectInformation: new Website(loggedInUser.getGitlabUserId()!, userProjects[project].name, userProjects[project].description,
+                      userProjects[project].id, userProjects[project].avatar_url, userProjects[project].path_with_namespace),
+                    pipelineStatus: await gitlabController.getProjectPipelineLatestStatus(userProjects[project].id)
+                  }
+                  gitlabPagesArr.push(page)
+                } else {
+                  const repo = new Repo(loggedInUser.getGitlabUserId()!, userProjects[project].name, userProjects[project].description,
+                    userProjects[project].id, userProjects[project].avatar_url, userProjects[project].path_with_namespace)
+                  gitlabReposArr.push(repo)
                 }
-                gitlabPagesArr.push(page)
-              } else {
-                const repo = new projectRepo(loggedInUser.getGitlabUserId()!, userProjects[project].name, userProjects[project].description,
-                  userProjects[project].id, userProjects[project].avatar_url, userProjects[project].path_with_namespace)
-                gitlabReposArr.push(repo)
               }
             }
-
             res.render(lang + '/account/services', {
               user: loggedInUser,
               gitlabRepos: gitlabReposArr,
@@ -297,7 +293,7 @@ export = function (app: any, config: any, passport: any, lang: string) {
         const newPwd = req.body.inputNewPwd
         const retypePwd = req.body.inputConfirm
 
-        dbconn.user.query('SELECT password FROM credential WHERE user_id=' + loggedInUser.getId(), function (err: any, rows: any) {
+        dbConnection.user.query('SELECT password FROM credential WHERE user_id=' + loggedInUser.getId(), function (err: any, rows: any) {
           if (err) {
             console.error(err)
             res.status(500).render(lang + '/500', { error: err })
@@ -313,7 +309,7 @@ export = function (app: any, config: any, passport: any, lang: string) {
               res.flash('error', 'Das Passwort ist leider falsch. Bitte überprüfen Sie Ihre Eingabe.')
               res.redirect('/account/security')
             } else {
-              if (newPwd != retypePwd) {
+              if (newPwd !== retypePwd) {
                 res.flash('error', 'Passwörter stimmen nicht überein. Bitte stellen Sie sicher, dass Sie das Passwort beide Male genau gleich eingeben.')
                 res.redirect('/account/security')
               } else {
@@ -333,8 +329,8 @@ export = function (app: any, config: any, passport: any, lang: string) {
                       res.flash('success', 'Passwort aktualisiert!')
                       // send notifiaction email
                       mailer.options.to = loggedInUser.getEmail()
-                      mailer.options.subject = constants.updatePasswordMailSubject
-                      mailer.options.html = constants.updatePasswordMailContent + '<div>' + constants.mailSignature + '</div>'
+                      mailer.options.subject = miscConst.updatePasswordMailSubject
+                      mailer.options.html = miscConst.updatePasswordMailContent + '<div>' + miscConst.mailSignature + '</div>'
                       mailer.transporter.sendMail(mailer.options, function (err: any) {
                         if (err) { console.log(err) }
                       })
@@ -368,7 +364,7 @@ export = function (app: any, config: any, passport: any, lang: string) {
             '<p>vielen Dank für Ihre Anmeldung am Transferportal der HFT Stuttgart. <br/>' +
             'Um Ihre Anmeldung zu bestätigen, klicken Sie bitte diesen Link: ' + config.app.host + '/verifyAccount?token=' + token +
             '<br/><br/>' +
-            'Ohne Bestätigung Ihres Kontos müssen wir Ihr Konto leider nach 7 Tagen löschen.</p><br/>' + constants.mailSignature +
+            'Ohne Bestätigung Ihres Kontos müssen wir Ihr Konto leider nach 7 Tagen löschen.</p><br/>' + miscConst.mailSignature +
             '</div>'
           mailer.options.to = loggedInUser.email
           mailer.options.subject = emailSubject
@@ -422,7 +418,7 @@ export = function (app: any, config: any, passport: any, lang: string) {
           const projectName = req.body.name.toLowerCase().replace(/\s/g, '-')
           const projectDesc = req.body.description
           const projectTemplate = req.body.template
-          const newInformation = new projectInformation(loggedInUser.getGitlabUserId()!, projectName, projectDesc)
+          const newInformation = new Website(loggedInUser.getGitlabUserId()!, projectName, projectDesc)
           let newLogoFile = defaultLogo
 
           if (req.files) { newLogoFile = req.files.logo }
@@ -441,7 +437,7 @@ export = function (app: any, config: any, passport: any, lang: string) {
             async function (newLogoFile: any) { // create a new GitLab Page
               const newPages = await gitlabController.createNewPages(newInformation, newLogoFile, projectTemplate)
               if (newPages.status) {
-                if (newPages.data.message.name == 'has already been taken') {
+                if (newPages.data.message.name === 'has already been taken') {
                   res.flash('error', "Der Projektname '" + newInformation.getName() + "' ist bereits vergeben, bitte wählen Sie einen anderen Namen.")
                 } else {
                   res.flash('error', 'Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut. ')
@@ -486,11 +482,11 @@ export = function (app: any, config: any, passport: any, lang: string) {
           } else if (!project.owner) {
             console.log(' ========= Project cannot be accessed, since it does not have an owner')
             res.redirect('/account/services')
-          } else if (project.owner.id != loggedInUser.getGitlabUserId()) {
+          } else if (project.owner.id !== loggedInUser.getGitlabUserId()) {
             console.log(' ========= Access denied: Not your project')
             res.redirect('/account/services')
           } else {
-            const curInformation = new projectInformation(loggedInUser.getGitlabUserId()!, project.name, project.description,
+            const curInformation = new Website(loggedInUser.getGitlabUserId()!, project.name, project.description,
               req.query.id, project.avatar_url, project.path_with_namespace)
 
             res.render(lang + '/account/updateInformation', {
@@ -518,7 +514,7 @@ export = function (app: any, config: any, passport: any, lang: string) {
         } else {
           const projectName = req.body.name.toLowerCase().replace(/\s/g, '-')
           const projectDesc = req.body.description
-          const updatedInformation = new projectInformation(loggedInUser.getGitlabUserId()!, projectName, projectDesc, req.query.id)
+          const updatedInformation = new Website(loggedInUser.getGitlabUserId()!, projectName, projectDesc, req.query.id)
           let newLogoFile: any
 
           async.waterfall([
@@ -548,7 +544,7 @@ export = function (app: any, config: any, passport: any, lang: string) {
                 res.flash('success', 'Ihre Website wurde aktualisiert')
               }
 
-              res.redirect('/account/updateInformation?id=' + updatedInformation.getId())
+              res.redirect('/account/updateInformation?id=' + String(updatedInformation.getId()))
             }
           ], function (err) {
             if (err != null) console.log(err)
@@ -580,7 +576,7 @@ export = function (app: any, config: any, passport: any, lang: string) {
             console.log(' ========= Error or no project found')
           } else if (!project.owner) {
             console.log(' ========= Project cannot be accessed, since it does not have an owner')
-          } else if (project.owner.id != loggedInUser.getGitlabUserId()) {
+          } else if (project.owner.id !== loggedInUser.getGitlabUserId()) {
             console.log(' ========= Access denied: Not your project')
           } else {
             const isDeleted = await gitlabController.deleteProjectById(projectId)
diff --git a/src/routes/public.ts b/src/routes/public.ts
index 151540674670e8b89085291f28f902dd65391574..14e5e1bb15d65e375217fe0280a1066fa6dd9958 100644
--- a/src/routes/public.ts
+++ b/src/routes/public.ts
@@ -1,95 +1,12 @@
-import async from 'async'
-import bcrypt from 'bcryptjs'
-import { dbController } from '../controller/dbController'
-import mailer from '../config/mailer'
-import constants from '../config/const'
 import { publicController } from '../controller/publicController'
 
-const saltRounds: number = 10
-const salt: number = 64
-
-export = function (app: any, config: any, lang: string) {
+module.exports = function (app: any, config: any, lang: any) {
   // ================== NEW USERS REGISTRATION ======================
   app.get('/registration', function (req: any, res: any) {
-    publicController.showRegistrationPage(res)
+    publicController.showRegistrationPage(res, lang)
   })
   app.post('/registration', function (req: any, res: any) {
-    // user data
-    const curDate: Date = new Date()
-    const userData: any = {
-      salutation: req.body.inputSalutation,
-      title: req.body.inputTitle,
-      firstname: req.body.inputFirstname,
-      lastname: req.body.inputLastname,
-      email: req.body.inputEmail,
-      organisation: req.body.inputOrganisation,
-      industry: req.body.inputIndustry,
-      speciality: req.body.inputSpeciality,
-      createdDate: curDate.toISOString().slice(0, 10)
-    }
-
-    const userEmail: any = userData.email
-    const pos: number = userEmail.indexOf('@')
-    const emailLength: number = userEmail.length
-    const emailDomain: any = userEmail.slice(pos, emailLength)
-
-    if (emailDomain.toLowerCase() == '@hft-stuttgart.de') {
-      res.flash('error', 'Fehlgeschlagen: HFT-Account')
-      res.redirect('/account/registration')
-    } else {
-      async.waterfall([
-        function (done: any) {
-          // generate token
-          let token: string = ''
-          const randomChars: string = 'abcdefghijklmnopqrstuvwxyz0123456789'
-          for (let i = 0; i < 40; i++) {
-            token += randomChars.charAt(Math.floor(Math.random() * randomChars.length))
-          }
-          // encrypt password
-          bcrypt.genSalt(saltRounds, function (err, salt) {
-            bcrypt.hash(req.body.inputPassword, salt, function (err: any, hash: any) {
-              const newAccount: any = {
-                profile: userData,
-                password: hash,
-                verificationToken: token
-              }
-              done(err, newAccount)
-            })
-          })
-        },
-        // save data
-        function (newAccount: any, err: any) {
-          dbController.registerNewUser(newAccount, function (err: any) {
-            if (err) {
-              res.flash('error', 'Fehlgeschlagen')
-            } else {
-              // send email
-              const emailSubject = 'Bitte bestätigen Sie Ihr M4_LAB Benutzerkonto'
-              const emailContent = '<div>Lieber Nutzer,<br/><br/>' +
-                '<p>vielen Dank für Ihre Anmeldung am Transferportal der HFT Stuttgart. <br/>' +
-                'Um Ihre Anmeldung zu bestätigen, klicken Sie bitte <a href=' + String(config.app.host) + '/verifyAccount?token=' + String(newAccount.verificationToken) + '>diesen Link</a> ' +
-                '<br/><br/>' +
-                'Ohne Bestätigung Ihres Kontos müssen wir Ihr Konto leider nach 7 Tagen löschen.</p><br/>' + String(constants.mailSignature) +
-                '</div>'
-              mailer.options.to = req.body.inputEmail
-              mailer.options.subject = emailSubject
-              mailer.options.html = emailContent
-              mailer.transporter.sendMail(mailer.options, function (err: any) {
-                if (err) {
-                  console.error('Cannot send email. [Error] ' + String(err))
-                  throw err
-                }
-              })
-              // user feedback
-              res.flash('success', 'Vielen Dank für Ihre Registrierung!' + '\r\n\r\n' +
-                'Wir haben Ihnen eine E-Mail an Ihre verwendete Adresse gesendet. Diese enthält einen Link zur Bestätigung Ihres Accounts.' + '\r\n' +
-                'Wenn Sie die Mail nicht in ihrem Postfach vorfinden, prüfen Sie bitte auch Ihren Spam-Ordner.')
-            }
-            res.redirect('/account/registration')
-          })
-        }
-      ])
-    }
+    publicController.registerUser(req, res, config)
   })
   // to check whether or not an account is already exist
   app.get('/email/:email', async function (req: any, res: any) {
@@ -99,157 +16,29 @@ export = function (app: any, config: any, lang: string) {
   // =================== USERS VERIFICATION =========================
 
   app.get('/verifyAccount', async function (req: any, res: any) {
-    const userId: number = await dbController.getUserIdByVerificationToken(req.query.token)
-    if (!userId) {
-      // no user found
-      res.render(lang + '/account/verification', {
-        status: null
-      })
-    } else {
-      // a user found, verify the account
-      const userData: any = {
-        id: userId,
-        verificationStatus: 1
-      }
-      dbController.verifyUserAccount(userData, async function (err: any) {
-        if (err) {
-          console.error(err)
-          res.render(lang + '/account/verification', {
-            status: false
-          })
-        } else {
-          // send welcome email after successful account verification
-          const userEmail: string = await dbController.getUserEmailById(userId)
-          if (!userEmail) {
-            res.render(lang + '/account/verification', {
-              status: false
-            })
-          } else {
-            // send email
-            const emailSubject = 'Herzlich willkommen'
-            const emailContent = '<div>Lieber Nutzer,<br/><br/>' +
-              '<p>herzlich willkommen beim Transferportal der HFT Stuttgart!<br/>' +
-              'Sie können nun alle Dienste des Portals nutzen.<p/><br/>' + constants.mailSignature
-            mailer.options.to = userEmail
-            mailer.options.subject = emailSubject
-            mailer.options.html = emailContent
-            mailer.transporter.sendMail(mailer.options, function (err: any) {
-              if (err) {
-                console.log('cannot send email')
-                throw err
-              }
-            })
-
-            res.render(lang + '/account/verification', {
-              status: true
-            })
-          }
-        }
-      })
-    }
+    publicController.verifyAccount(req, res, lang)
   })
 
   // ==================== FORGOT PASSWORD ===========================
 
   app.get('/forgotPwd', function (req: any, res: any) {
-    publicController.showForgotPwdPage(req, res)
+    publicController.showForgotPwdPage(req, res, lang)
   })
   app.post('/forgotPwd', function (req: any, res: any) {
-    const emailAddress = req.body.inputEmail
-    async.waterfall([
-      async function (done: any) {
-        const user = await dbController.checkUserEmail(emailAddress)
-        if (!user) {
-          console.log('No user found: ' + String(emailAddress))
-        } else {
-          // generate token
-          let token: string = ''
-          const randomChars: string = 'abcdefghijklmnopqrstuvwxyz0123456789'
-          for (let i = 0; i < 40; i++) {
-            token += randomChars.charAt(Math.floor(Math.random() * randomChars.length))
-          }
-
-          const emailSubject = 'Ihre Passwort-Anfrage an das Transferportal der HFT Stuttgart'
-          const emailContent = '<div>Lieber Nutzer,<br/><br/>' +
-            '<p>wir haben Ihre Anfrage zur Erneuerung Ihres Passwortes erhalten. Falls Sie diese Anfrage nicht gesendet haben, ignorieren Sie bitte diese E-Mail.<br/><br/>' +
-            'Sie können Ihr Passwort mit dem Klick auf diesen Link ändern: ' + String(config.app.host) + '/reset/' + String(token) + '<br/>' +
-            'Dieser Link ist aus Sicherheitsgründen nur für 1 Stunde gültig.<br/></p>' + String(constants.mailSignature) + '</div>'
-
-          const credentialData = {
-            user_id: user.id,
-            resetPasswordToken: token,
-            resetPasswordExpires: Date.now() + 3600000 // 1 hour
-          }
-          const result = await dbController.updateCredential(credentialData)
-          if (!result) {
-            console.log('failed to update credential')
-          } else {
-            // send email
-            mailer.options.to = emailAddress
-            mailer.options.subject = emailSubject
-            mailer.options.html = emailContent
-            mailer.transporter.sendMail(mailer.options, function (err: any) {
-              if (err) { console.error(err) }
-            })
-          }
-        }
-        done(null)
-      }
-    ], function (err: any) {
-      if (err) {
-        res.flash('error', 'Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.')
-      } else {
-        res.flash('success', 'Wenn Ihre E-Mail-Adresse registriert ist, wurde eine E-Mail mit dem weiteren Vorgehen an ' + String(emailAddress) + ' versendet.')
-      }
-      res.redirect('/account/forgotPwd')
-    })
+    publicController.generateNewToken(req, res, config)
   })
 
   // reset
   app.get('/reset/:token', async function (req: any, res: any) {
-    publicController.showResetToken(req, res)
+    publicController.showResetPassword(req, res, lang)
   })
   app.post('/reset/:token', async function (req: any, res: any) {
-    const newPwd = req.body.inputNewPwd
-
-    const user = await dbController.getUserByToken(req.params.token)
-    if (!user) {
-      res.flash('error', 'User not found.')
-      res.redirect('/login')
-    } else {
-      // encrypt password
-      bcrypt.genSalt(saltRounds, function (err, salt) {
-        bcrypt.hash(newPwd, salt, async function (err: any, hash) {
-          const credentialData = {
-            password: hash,
-            user_id: user.user_id,
-            resetPasswordToken: null,
-            resetPasswordExpires: null
-          }
-          // update password
-          const result = await dbController.updateCredential(credentialData)
-          if (!result) {
-            console.log('Failed to reset password')
-            res.flash('error', 'Datenbankfehler: Passwort kann nicht geändert werden.')
-          } else {
-            res.flash('success', 'Passwort aktualisiert!')
-            // send notification email
-            mailer.options.to = user.email
-            mailer.options.subject = constants.updatePasswordMailSubject
-            mailer.options.html = constants.updatePasswordMailContent + '<div>' + constants.mailSignature + '</div>'
-            mailer.transporter.sendMail(mailer.options, function (err: any) {
-              if (err) { console.log(err) }
-            })
-          }
-          res.redirect('/login')
-        })
-      })
-    }
+    publicController.resetPassword(req, res)
   })
 
   // ======================= CONTACT FORM ===========================
   app.get('/contact', function (req: any, res: any) {
-    publicController.showContactPage(req, res)
+    publicController.showContactPage(req, res, lang)
   })
   app.post('/contact', function (req: any, res: any) {
     publicController.sendContactMessage(req, res)
diff --git a/src/views/DE/account/services.pug b/src/views/DE/account/services.pug
index 46c91bc297dc7abeacb21b06db0dd027fc6a8ca5..f03fd1f72e6cb957313dd4ad5ee8da31aebfb910 100644
--- a/src/views/DE/account/services.pug
+++ b/src/views/DE/account/services.pug
@@ -78,6 +78,9 @@ html(lang="de")
                                     div(class="col text-right")
                                         button(type="button", class="btn btn-sm btn-success" disabled) Neuer Projektdatensatz
                             table(class="table")
+                                if gitlabRepos.length == 0
+                                    tr
+                                        td Currently you have no project codes/data
                                 for item in gitlabRepos
                                     - let img = item.logo
                                     tr