From 5523f3fa71f07e75e08127a1879cf3549f55a6e9 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Fri, 28 Feb 2020 09:39:11 +0100
Subject: [PATCH 01/20] update saml config

---
 config/config.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/config/config.js b/config/config.js
index 236e7943..16e1a3e6 100644
--- a/config/config.js
+++ b/config/config.js
@@ -8,9 +8,9 @@ module.exports = {
       strategy: 'saml',
       saml: {
         path: process.env.SAML_PATH || '/saml/SSO',
-        entryPoint: process.env.SAML_ENTRY_POINT || 'https://transfer.hft-stuttgart.de/idp/saml2/idp/SSOService.php',
+        entryPoint: process.env.SAML_ENTRY_POINT || 'https://m4lab.hft-stuttgart.de/idp/saml2/idp/SSOService.php',
         issuer: 'sp-account.m4lab.hft-stuttgart.de',
-        logoutUrl: 'https://transfer.hft-stuttgart.de/idp/saml2/idp/SingleLogoutService.php'
+        logoutUrl: 'https://m4lab.hft-stuttgart.de/idp/saml2/idp/SingleLogoutService.php'
       }
     },
     database: {
-- 
GitLab


From 49e5a58df82538be0498d5ff13143a3238c547a4 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Fri, 28 Feb 2020 09:40:16 +0100
Subject: [PATCH 02/20] update forgot password email and user feedback

---
 routes/routes.js | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/routes/routes.js b/routes/routes.js
index 7b71ded6..af04837d 100644
--- a/routes/routes.js
+++ b/routes/routes.js
@@ -350,10 +350,10 @@ module.exports = function (app, config, passport) {
     //methods.currentDate();
 
     var emailAddress = req.body.inputEmail;
-    var emailContent = "Hi there,\n\n"+
+  /*  var emailContent = "Hi there,\n\n"+
       "we've received a request to reset your password. However, this email address is not on our database of registered users.\n\n"+
       "Thanks,\nM4_LAB Team";
-    var emailSubject = "Account Access Attempted";
+    var emailSubject = "Account Access Attempted"; */
     
     async.waterfall([
       function(done) {
@@ -366,8 +366,8 @@ module.exports = function (app, config, passport) {
         methods.checkUserEmail(emailAddress, function(err, user){
           if (user) {
             console.log("email: user found");
-            emailSubject = "M4_LAB Password Reset";
-            emailContent = "Hi User,\n\n"+
+            var emailSubject = "M4_LAB Password Reset";
+            var emailContent = "Hi User,\n\n"+
               "we've received a request to reset your password. If you didn't make the request, just ignore this email.\n\n"+
               "Otherwise, you can reset your password using this link: http://localhost:9989/reset/" + token + "\n" +
               "This password reset is only valid for 1 hour.\n\n"+
@@ -381,12 +381,22 @@ module.exports = function (app, config, passport) {
             methods.updateCredential(credentialData, function(err) {
               done(err, token, user);
             });
+
+            // send email
+            mailOptions.to = emailAddress;
+            mailOptions.subject = emailSubject;
+            mailOptions.text = emailContent;
+            smtpTransport.sendMail(mailOptions, function(err) {
+              done(err, 'done');
+            });
           }
           else {
-            done(err, null, null);
+            //done(err, null, null);
+            done(err, 'no user found');
           }
         });
-      },
+      }
+      /*,
       function(token, user, done) {
         mailOptions.to = emailAddress;
         mailOptions.subject = emailSubject;
@@ -394,13 +404,13 @@ module.exports = function (app, config, passport) {
         smtpTransport.sendMail(mailOptions, function(err) {
           done(err, 'done');
         });
-      }
+      } */
     ], function(err) {
       if (err) {
         req.flash('error', 'An error occured. Please try again.');
       }
       else {
-        req.flash('success', 'An e-mail has been sent to ' + emailAddress + ' with further instructions.');
+        req.flash('success', 'If your email is registered, an e-mail has been sent to ' + emailAddress + ' with further instructions.');
       }
       res.redirect('/forgotPwd');
     });
-- 
GitLab


From 5968a7dae9083a95575c19acb0bb8e49a3504f0c Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Fri, 28 Feb 2020 14:32:56 +0100
Subject: [PATCH 03/20] add i18n dependency and test

---
 app.js            | 12 +++++++--
 locales/de.json   |  4 +++
 locales/en.json   |  4 +++
 package-lock.json | 63 +++++++++++++++++++++++++++++++++++++++++++++++
 package.json      |  1 +
 routes/routes.js  | 44 +++++++++++++++++++--------------
 6 files changed, 107 insertions(+), 21 deletions(-)
 create mode 100644 locales/de.json
 create mode 100644 locales/en.json

diff --git a/app.js b/app.js
index 0feeba4c..bcbbfbfe 100644
--- a/app.js
+++ b/app.js
@@ -8,6 +8,7 @@ const bodyParser = require('body-parser');
 const session = require('express-session');
 const errorhandler = require('errorhandler');
 const flash = require('express-flash');
+const i18n = require('i18n'); // internationalization
 
 var env = process.env.NODE_ENV || 'development';
 const config = require('./config/config')[env];
@@ -47,10 +48,17 @@ app.use(function(req, res, next) {
   next();
 });
 
-require('./routes/routes')(app, config, passport);
+// internationalization (i18n)
+i18n.configure({
+  locales:['de', 'en'],
+  directory: './locales'
+});
+app.use(i18n.init);
+
+require('./routes/routes')(app, config, passport, i18n);
 //require('./routes/dbconn')(app, config);
 require('./routes/api')(app, config, passport);
 
 app.listen(app.get('port'), function () {
   console.log('Express server listening on port ' + app.get('port'));
-});
+});
\ No newline at end of file
diff --git a/locales/de.json b/locales/de.json
new file mode 100644
index 00000000..13a9c092
--- /dev/null
+++ b/locales/de.json
@@ -0,0 +1,4 @@
+{
+	"Hello World": "Hallo Welt",
+	"Hello": "Hallo"
+}
\ No newline at end of file
diff --git a/locales/en.json b/locales/en.json
new file mode 100644
index 00000000..0873ff89
--- /dev/null
+++ b/locales/en.json
@@ -0,0 +1,4 @@
+{
+	"Hello World": "Hello World",
+	"Hello": "Hello",
+}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 7e0b9410..1d68e8a5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -748,6 +748,19 @@
         }
       }
     },
+    "i18n": {
+      "version": "0.8.5",
+      "resolved": "https://registry.npmjs.org/i18n/-/i18n-0.8.5.tgz",
+      "integrity": "sha512-6UgLbhJGgn4XFeuZc/dDdrrri0ij24EK4hxv4Pbi5hloYAZ1B2+0eQchEryBFezLKYOHhVGV/5+H4i0oxng94w==",
+      "requires": {
+        "debug": "*",
+        "make-plural": "^6.0.1",
+        "math-interval-parser": "^2.0.1",
+        "messageformat": "^2.3.0",
+        "mustache": "*",
+        "sprintf-js": "^1.1.2"
+      }
+    },
     "iconv-lite": {
       "version": "0.4.24",
       "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -982,6 +995,16 @@
         "pify": "^3.0.0"
       }
     },
+    "make-plural": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-6.0.1.tgz",
+      "integrity": "sha512-h0uBNi4tpDkiWUyYKrJNj8Kif6q3Ba5zp/8jnfPy3pQE+4XcTj6h3eZM5SYVUyDNX9Zk69Isr/dx0I+78aJUaQ=="
+    },
+    "math-interval-parser": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/math-interval-parser/-/math-interval-parser-2.0.1.tgz",
+      "integrity": "sha512-VmlAmb0UJwlvMyx8iPhXUDnVW1F9IrGEd9CIOmv+XL8AErCUUuozoDMrgImvnYt2A+53qVX/tPW6YJurMKYsvA=="
+    },
     "media-typer": {
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@@ -992,6 +1015,36 @@
       "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
       "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
     },
+    "messageformat": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/messageformat/-/messageformat-2.3.0.tgz",
+      "integrity": "sha512-uTzvsv0lTeQxYI2y1NPa1lItL5VRI8Gb93Y2K2ue5gBPyrbJxfDi/EYWxh2PKv5yO42AJeeqblS9MJSh/IEk4w==",
+      "requires": {
+        "make-plural": "^4.3.0",
+        "messageformat-formatters": "^2.0.1",
+        "messageformat-parser": "^4.1.2"
+      },
+      "dependencies": {
+        "make-plural": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-4.3.0.tgz",
+          "integrity": "sha512-xTYd4JVHpSCW+aqDof6w/MebaMVNTVYBZhbB/vi513xXdiPT92JMVCo0Jq8W2UZnzYRFeVbQiQ+I25l13JuKvA==",
+          "requires": {
+            "minimist": "^1.2.0"
+          }
+        }
+      }
+    },
+    "messageformat-formatters": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/messageformat-formatters/-/messageformat-formatters-2.0.1.tgz",
+      "integrity": "sha512-E/lQRXhtHwGuiQjI7qxkLp8AHbMD5r2217XNe/SREbBlSawe0lOqsFb7rflZJmlQFSULNLIqlcjjsCPlB3m3Mg=="
+    },
+    "messageformat-parser": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/messageformat-parser/-/messageformat-parser-4.1.2.tgz",
+      "integrity": "sha512-7dWuifeyldz7vhEuL96Kwq1fhZXBW+TUfbnHN4UCrCxoXQTYjHnR78eI66Gk9LaLLsAvzPNVJBaa66DRfFNaiA=="
+    },
     "methods": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
@@ -1045,6 +1098,11 @@
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
       "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
     },
+    "mustache": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.0.0.tgz",
+      "integrity": "sha512-FJgjyX/IVkbXBXYUwH+OYwQKqWpFPLaLVESd70yHjSDunwzV2hZOoTBvPf4KLoxesUzzyfTH6F784Uqd7Wm5yA=="
+    },
     "mysql": {
       "version": "2.17.1",
       "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.17.1.tgz",
@@ -1686,6 +1744,11 @@
       "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
       "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
     },
+    "sprintf-js": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
+      "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug=="
+    },
     "sqlstring": {
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
diff --git a/package.json b/package.json
index 93d0dbbf..2c3a2562 100644
--- a/package.json
+++ b/package.json
@@ -31,6 +31,7 @@
     "express-flash": "0.0.2",
     "express-session": "^1.17.0",
     "fs": "0.0.1-security",
+    "i18n": "^0.8.5",
     "morgan": "^1.9.1",
     "mysql": "^2.17.1",
     "nodemailer": "^6.3.1",
diff --git a/routes/routes.js b/routes/routes.js
index b0e32625..c55b88e1 100644
--- a/routes/routes.js
+++ b/routes/routes.js
@@ -11,7 +11,7 @@ const async = require('async')
 const crypto = require('crypto')
 const nodemailer = require('nodemailer')
 
-module.exports = function (app, config, passport) {
+module.exports = function (app, config, passport, i18n) {
 
   // =========== PASSPORT =======
   passport.serializeUser(function (user, done) {
@@ -54,17 +54,6 @@ module.exports = function (app, config, passport) {
   
   passport.use(samlStrategy);
 
-  // ============================
-/*
-  app.all('/', function(req, res){
-    req.flash('test', 'it worked');
-    res.redirect('/test')
-  });
-  app.all('/test', function(req, res){
-    res.send(JSON.stringify(req.flash('test')));
-  });
-  */
-
   // ============= SAML ==============
   app.post(config.passport.saml.path,
     passport.authenticate(config.passport.strategy,
@@ -111,17 +100,34 @@ module.exports = function (app, config, passport) {
     "We would like to notify that your password has been successfully updated.\n\n"+
     "Thanks,\nM4_LAB Team"
   var updatePasswordMailSubject = "Your M4_LAB Password has been updated"
+
+  // ================ test i18n ==================
+  i18n.setLocale('de');
+  app.get('/de', function(req, res) {
+    var greeting = i18n.__('Hello World')
+    res.send(greeting)
+  });
   
   // ======== APP ROUTES ====================
-  app.get('/', function (req, res) {
-    res.redirect('/profile')
+  app.get('/account', function (req, res) {
+    if (req.isAuthenticated()) {
+      methods.getUserByEmail(req.user.email, function(data, err){
+        if (!err) {
+          res.render('home', {
+            greeting: i18n.__('Hello'),
+          });
+        }
+      })
+    } else {
+      res.redirect('/account/login');
+    }
   });
 
   app.get('/error', function (req, res) {
     res.render('error')
   });
 
-  app.get('/login',
+  app.get('/account/login',
     passport.authenticate(config.passport.strategy,
       {
         successRedirect: '/account/',
@@ -131,7 +137,7 @@ module.exports = function (app, config, passport) {
 
   app.get('/logout', function (req, res) {
     if (req.user == null) {
-      return res.redirect('/account/');
+      return res.redirect('https://m4lab.hft-stuttgart.de');
     }
     
     req.user.nameID = req.user.id;
@@ -151,7 +157,7 @@ module.exports = function (app, config, passport) {
     });
   });
 
-  app.get('/profile', function (req, res) {
+  app.get('/account/profile', function (req, res) {
     if (req.isAuthenticated()) {
       methods.getUserByEmail(req.user.email, function(data, err){
         if (!err) {
@@ -166,7 +172,7 @@ module.exports = function (app, config, passport) {
     }
   });
 
-  app.get('/services', function (req, res) {
+  app.get('/account/services', function (req, res) {
     if (req.isAuthenticated()) {
       async.waterfall([
         // get userId by email from userdb
@@ -230,7 +236,7 @@ module.exports = function (app, config, passport) {
     }
   });
 
-  app.get('/security', function (req, res) {
+  app.get('/account/security', function (req, res) {
     if (req.isAuthenticated()) {
       res.render('security', {
         user: req.user // useful for view engine, useless for HTML
-- 
GitLab


From b9cfe96481d094cd51c13e1249b814baa8701a83 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Fri, 28 Feb 2020 14:33:51 +0100
Subject: [PATCH 04/20] Introductory page of User Account

---
 views/home.pug | 61 ++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 49 insertions(+), 12 deletions(-)

diff --git a/views/home.pug b/views/home.pug
index 285666ec..cea90b4e 100644
--- a/views/home.pug
+++ b/views/home.pug
@@ -1,12 +1,49 @@
-extends layout
-
-block content
-	if user !== null
-		h1 Hello, #{user.firstName}
-		a(href="/account/profile") Profile
-		br
-		a(href="/account/logout") Logout
-	else
-		h1 Welcome
-		br
-		a(href="/account/login") Login
+doctype html
+html(lang="en")
+  head
+    title= "User Account"
+    meta(charset="UTF-8")
+    meta(name="viewport", content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no")
+    link(rel="stylesheet", type="text/css", href="https://transfer.hft-stuttgart.de/css/bootstrap/bootstrap.css")
+    link(rel="stylesheet", href="https://use.fontawesome.com/releases/v5.8.2/css/all.css", integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay", crossorigin="anonymous")
+    style.
+        .collapse {
+            display: none;
+        }
+        .collapse.in {
+            display: block;
+        }
+        .collapsing {
+            position: relative;
+            height: 0;
+            overflow: hidden;
+            -webkit-transition-timing-function: ease;
+            -o-transition-timing-function: ease;
+            transition-timing-function: ease;
+            -webkit-transition-duration: .35s;
+            -o-transition-duration: .35s;
+            transition-duration: .35s;
+            -webkit-transition-property: height,visibility;
+            -o-transition-property: height,visibility;
+            transition-property: height,visibility;
+        }
+  body
+    div(class="container-fluid")
+        div(class="row")
+            div(class="col-3")
+                h5
+                    span #{greeting}
+                div(class="nav flex-column nav-pills", id="v-pills-tab", role="tablist", aria-orientation="vertical")
+                    a(class="nav-link" href="#" aria-selected="true") Profile
+                    a(class="nav-link" href="/account/security" aria-selected="false") Security
+                    a(class="nav-link" href="/account/services" aria-selected="false") Services
+            div(class="col-sm-9")
+                p content goes here
+                
+    // jQuery
+    script(src="https://code.jquery.com/jquery-3.3.1.min.js")
+    script(src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js", integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1", crossorigin="anonymous")
+    // Bootstrap
+    script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous")
+    // M4_LAB
+    script(src="/js/headfootLogout.js")
\ No newline at end of file
-- 
GitLab


From 8ce885d3a532c64ebcf2342a7dcc7c4241566161 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Fri, 28 Feb 2020 17:14:38 +0100
Subject: [PATCH 05/20] delete unused pages

---
 views/TBD/profile-old.html  | 113 ------------------------------------
 views/TBD/profile-old.pug   |   1 -
 views/TBD/security-old.html | 111 -----------------------------------
 views/TBD/security-old.pug  |   1 -
 4 files changed, 226 deletions(-)
 delete mode 100644 views/TBD/profile-old.html
 delete mode 100644 views/TBD/profile-old.pug
 delete mode 100644 views/TBD/security-old.html
 delete mode 100644 views/TBD/security-old.pug

diff --git a/views/TBD/profile-old.html b/views/TBD/profile-old.html
deleted file mode 100644
index 2b18262f..00000000
--- a/views/TBD/profile-old.html
+++ /dev/null
@@ -1,113 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-	    <title>User Profile</title>
-	    <meta charset="UTF-8"/>
-	    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
-	    <link rel="stylesheet" type="text/css" href="https://transfer.hft-stuttgart.de/css/bootstrap/bootstrap.css" />
-	    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css" integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay" crossorigin="anonymous" />
-	    <style>
-			.collapse {
-				display: none;
-			}
-			.collapse.in {
-				display: block;
-			}
-			.collapsing {
-				position: relative;
-				height: 0;
-				overflow: hidden;
-				-webkit-transition-timing-function: ease;
-				-o-transition-timing-function: ease;
-				transition-timing-function: ease;
-				-webkit-transition-duration: .35s;
-				-o-transition-duration: .35s;
-				transition-duration: .35s;
-				-webkit-transition-property: height,visibility;
-				-o-transition-property: height,visibility;
-				transition-property: height,visibility;
-			}	    
-		</style>
-	</head>
-	
-	<body>
-		
-		<!-- CONTENT -->
-		<div class="container-fluid">
-		  <div class="row">
-		    <!-- https://getbootstrap.com/docs/4.3/components/navs/ -->
-		    <div class="col-3">
-		    	<h5>
-			    	<span id="fullname"></span>
-			    </h5>
-			    <div class="nav flex-column nav-pills" id="v-pills-tab" role="tablist" aria-orientation="vertical">
-			      <a class="nav-link" href="#" aria-selected="true">Profile</a>
-			      <a class="nav-link" href="/security" aria-selected="false">Security</a>
-			      <a class="nav-link" href="#" aria-selected="false">Services</a>
-			    </div>
-			  </div>
-		
-		    <div class="col-sm-9">
-				<form id="profileForm" method="POST" action="/updateProfile">
-		            <!-- p><input type="hidden" th:value="${id}"/></p -->
-		                	
-		            <table class="table table-borderless">
-						<tr>
-						    <th><label for="title">Title</label></th>
-						    <td><input id="inputTitle" name="inputTitle" type="text" placeholder="Title"></td> 
-						</tr>
-						<tr>
-						    <th><label for="firstname">Vorname</label></th>
-						    <td><input id="inputFirstname" name="inputFirstname" type="text" placeholder="Vorname" required></td>
-					    </tr>
-						<tr>
-						    <th><label for="lastname">Nachname</label></th>
-						    <td><input id="inputLastname" name="inputLastname" type="text" placeholder="Nachname" required></td>
-					    </tr>
-						<tr>
-						    <th><label for="email">Email</label></th>
-						    <td><input id="inputEmail" name="inputEmail" type="text" placeholder="Email" required></td>
-						</tr>
-						<tr>
-						    <th><label for="organisation">Unternehmen</label></th>
-						    <td><input id="inputOrganisation" name="inputOrganisation" type="text" placeholder="Unternehmen"></td>
-						</tr>
-					    <tr>
-							<th><label for="industry">Branche</label></th>
-						    <td><input id="inputIndustry" name="inputIndustry" type="text" placeholder="Branche"></td>
-						</tr>
-						<tr>
-							<th><label for="speciality">Fachgebiete</label></th>
-						    <td><input id="inputSpeciality" name="inputSpeciality" type="text" placeholder="Fachgebiete"></td>
-						</tr>
-					</table>
-						    
-					<p><input type="submit" class="btn btn-primary" value="Update"></p>   
-				</form>	      
-		    </div>
-		  </div>
-		</div>
-
-		<!-- jQuery -->
-		<!-- script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script -->
-		<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
-		<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
-		<!-- Bootstrap -->
-		<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
-		<!-- M4_LAB -->
-		<script src="/js/account.js"></script>
-		<script src="https://transfer.hft-stuttgart.de/js/headfoot.js"></script>
-		<script>
-		/*	$( document ).ready(function() {
-				console.log( "ready!" );
-				$.get( "/api/v1/profile", function(data) {
-					alert( "success: "+data );
-				})
-			}); */
-			$(function(){
-				$("#header").load("fragment/header.html"); 
-				$("#footer").load("fragment/footer.html"); 
-			});
-		</script> 
-	</body>
-</html>
\ No newline at end of file
diff --git a/views/TBD/profile-old.pug b/views/TBD/profile-old.pug
deleted file mode 100644
index 6f03f645..00000000
--- a/views/TBD/profile-old.pug
+++ /dev/null
@@ -1 +0,0 @@
-include profile.html
\ No newline at end of file
diff --git a/views/TBD/security-old.html b/views/TBD/security-old.html
deleted file mode 100644
index a47b1e56..00000000
--- a/views/TBD/security-old.html
+++ /dev/null
@@ -1,111 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-	    <title>User Profile</title>
-	    <meta charset="UTF-8"/>
-	    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
-	    <link rel="stylesheet" type="text/css" href="https://transfer.hft-stuttgart.de/css/bootstrap/bootstrap.css" />
-	    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css" integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay" crossorigin="anonymous" />
-	    <style>
-			.collapse {
-				display: none;
-			}
-			.collapse.in {
-				display: block;
-			}
-			.collapsing {
-				position: relative;
-				height: 0;
-				overflow: hidden;
-				-webkit-transition-timing-function: ease;
-				-o-transition-timing-function: ease;
-				transition-timing-function: ease;
-				-webkit-transition-duration: .35s;
-				-o-transition-duration: .35s;
-				transition-duration: .35s;
-				-webkit-transition-property: height,visibility;
-				-o-transition-property: height,visibility;
-				transition-property: height,visibility;
-			}	    
-		</style>
-	</head>
-	
-	<body>
-		
-		<!-- CONTENT -->
-		<div class="container-fluid">
-		  <div class="row">
-		    <!-- https://getbootstrap.com/docs/4.3/components/navs/ -->
-		    <div class="col-3">
-		    	<h5>
-			    	<span id="fullname"></span>
-			    </h5>
-			    <div class="nav flex-column nav-pills" id="v-pills-tab" role="tablist" aria-orientation="vertical">
-			      <a class="nav-link" href="/profile" aria-selected="true">Profile</a>
-			      <a class="nav-link" href="#" aria-selected="false">Security</a>
-			      <a class="nav-link" href="#" aria-selected="false">Services</a>
-			    </div>
-			</div>
-		
-		    <div class="col-sm-9">
-				<form method="post" class="needs-validation" action="/changePwd" novalidate>
-					<div class="form-group row">
-						<label for="currPwd">Current Password</label>
-						<input type="password" class="form-control" id="inputCurrPwd" name="inputCurrPwd" required>
-						<div class="invalid-feedback">Please fill in this field.</div>
-					</div>
-					<div class="form-group row">
-						<label for="newPwd">New Password</label>
-						<input type="password" class="form-control" id="inputNewPwd" name="inputNewPwd" required>
-						<div class="invalid-feedback">Please fill in this field.</div>
-					</div>
-					<div class="form-group row">
-						<label for="retype">Re-type New Password</label>
-						<input type="password" class="form-control" id="inputRetype" name="inputRetype" required>
-						<div class="invalid-feedback">Please fill in this field.</div>
-					</div>
-					<button type="submit" class="btn btn-primary">Submit</button>
-				</form>	      
-		    </div>
-		  </div>
-		</div>
-
-		<!-- jQuery -->
-		<!-- script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script -->
-		<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
-		<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
-		<!-- Bootstrap -->
-		<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
-		<!-- M4_LAB -->
-		<script src="/js/account.js"></script>
-		<script src="https://transfer.hft-stuttgart.de/js/headfoot.js"></script>
-		<script>
-		/*	$( document ).ready(function() {
-				console.log( "ready!" );
-				$.get( "/api/v1/profile", function(data) {
-					alert( "success: "+data );
-				})
-			}); */
-			$(function(){
-				$("#header").load("fragment/header.html"); 
-				$("#footer").load("fragment/footer.html"); 
-			});
-			// check input fields
-			'use strict';
-			window.addEventListener('load', function() {
-				// Fetch all the forms we want to apply custom Bootstrap validation styles to
-				var forms = document.getElementsByClassName('needs-validation');
-				// Loop over them and prevent submission
-				var validation = Array.prototype.filter.call(forms, function(form) {
-				form.addEventListener('submit', function(event) {
-					if (form.checkValidity() === false) {
-					event.preventDefault();
-					event.stopPropagation();
-					}
-					form.classList.add('was-validated');
-				}, false);
-				});
-			}, false);
-		</script> 
-	</body>
-</html>
\ No newline at end of file
diff --git a/views/TBD/security-old.pug b/views/TBD/security-old.pug
deleted file mode 100644
index e7c91985..00000000
--- a/views/TBD/security-old.pug
+++ /dev/null
@@ -1 +0,0 @@
-include security.html
\ No newline at end of file
-- 
GitLab


From 0468b335dabfb7750be7345592e79988cbfed428 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Fri, 28 Feb 2020 20:46:23 +0100
Subject: [PATCH 06/20] delete unused pages

---
 public/views_TBD/404.jade     |   4 --
 public/views_TBD/500.jade     |   8 ---
 public/views_TBD/error.jade   |   6 --
 public/views_TBD/home.jade    |  12 ----
 public/views_TBD/layout.jade  |  12 ----
 public/views_TBD/profile.html | 105 ----------------------------------
 public/views_TBD/profile.jade |   1 -
 7 files changed, 148 deletions(-)
 delete mode 100644 public/views_TBD/404.jade
 delete mode 100644 public/views_TBD/500.jade
 delete mode 100644 public/views_TBD/error.jade
 delete mode 100644 public/views_TBD/home.jade
 delete mode 100644 public/views_TBD/layout.jade
 delete mode 100644 public/views_TBD/profile.html
 delete mode 100644 public/views_TBD/profile.jade

diff --git a/public/views_TBD/404.jade b/public/views_TBD/404.jade
deleted file mode 100644
index dc9e0a8c..00000000
--- a/public/views_TBD/404.jade
+++ /dev/null
@@ -1,4 +0,0 @@
-extends error
-
-block content
-  h2 Cannot find #{url}
\ No newline at end of file
diff --git a/public/views_TBD/500.jade b/public/views_TBD/500.jade
deleted file mode 100644
index cbc47e79..00000000
--- a/public/views_TBD/500.jade
+++ /dev/null
@@ -1,8 +0,0 @@
-extends error
-
-block content
-  h1 Error: #{error.message}
-  if settings['verbose errors']
-    pre= error.stack
-  else
-    p An error ocurred!
\ No newline at end of file
diff --git a/public/views_TBD/error.jade b/public/views_TBD/error.jade
deleted file mode 100644
index bf750c00..00000000
--- a/public/views_TBD/error.jade
+++ /dev/null
@@ -1,6 +0,0 @@
-html
-  head 
-    title Error
-  body
-    h1 An error occurred!
-    block content
\ No newline at end of file
diff --git a/public/views_TBD/home.jade b/public/views_TBD/home.jade
deleted file mode 100644
index 2c704c1a..00000000
--- a/public/views_TBD/home.jade
+++ /dev/null
@@ -1,12 +0,0 @@
-extends layout
-
-block content
-	if user !== null
-		h1 Hello, #{user.firstName}
-		a(href="/profile") Profile
-		br
-		a(href="/logout") Logout
-	else
-		h1 Welcome
-		br
-		a(href="/login") Login
diff --git a/public/views_TBD/layout.jade b/public/views_TBD/layout.jade
deleted file mode 100644
index 32d27e01..00000000
--- a/public/views_TBD/layout.jade
+++ /dev/null
@@ -1,12 +0,0 @@
-doctype html
-html
-    head
-        title PassportJS SAML example
-        block links
-            link(rel='stylesheet', href='bower_components/bootstrap/dist/css/bootstrap.css')
-    body
-        div.container
-            block content
-        script(src='bower_components/jquery/dist/jquery.min.js')
-        script(src='bower_components/bootstrap/dist/js/bootstrap.min.js')
-        block scripts
diff --git a/public/views_TBD/profile.html b/public/views_TBD/profile.html
deleted file mode 100644
index 723f2815..00000000
--- a/public/views_TBD/profile.html
+++ /dev/null
@@ -1,105 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
-	    <title>User Profile</title>
-	    <meta charset="UTF-8"/>
-	    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
-	    <link rel="stylesheet" type="text/css" href="https://transfer.hft-stuttgart.de/css/bootstrap/bootstrap.css" />
-	    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css" integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay" crossorigin="anonymous" />
-	    <style>
-			.collapse {
-				display: none;
-			}
-			.collapse.in {
-				display: block;
-			}
-			.collapsing {
-				position: relative;
-				height: 0;
-				overflow: hidden;
-				-webkit-transition-timing-function: ease;
-				-o-transition-timing-function: ease;
-				transition-timing-function: ease;
-				-webkit-transition-duration: .35s;
-				-o-transition-duration: .35s;
-				transition-duration: .35s;
-				-webkit-transition-property: height,visibility;
-				-o-transition-property: height,visibility;
-				transition-property: height,visibility;
-			}	    
-		</style>
-	    
-	    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
-		<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
-        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
-        <script>
-            $(function(){
-                $("#header").load("fragment/header.html"); 
-                $("#footer").load("fragment/footer.html"); 
-            });
-        </script> 
-	</head>
-	
-	<body>
-		
-		<!-- CONTENT -->
-		<div class="container-fluid">
-		  <div class="row">
-		    <!-- https://getbootstrap.com/docs/4.3/components/navs/ -->
-		    <div class="col-3">
-		    	<h5>
-                    <!-- TODO: Firstname + Lastname-->
-			    	<span>TODO: Firstname + Lastname</span>
-			    </h5>
-			    <div class="nav flex-column nav-pills" id="v-pills-tab" role="tablist" aria-orientation="vertical">
-			      <a class="nav-link" href="#" aria-selected="true">Profile</a>
-			      <a class="nav-link" href="#" aria-selected="false">Security</a>
-			      <a class="nav-link" href="#" aria-selected="false">Services</a>
-			    </div>
-			  </div>
-		
-		    <div class="col-sm-9">
-				<form>
-		            <p><input type="hidden" th:value="${id}"/></p>
-		                	
-		            <table class="table table-borderless">
-						<tr>
-						    <th><label for="title">Title</label></th>
-						    <td><input type="text" placeholder="Title"></td> 
-						</tr>
-						<tr>
-						    <th><label for="firstname">Vorname</label></th>
-						    <td><input type="text" placeholder="Vorname"></td>
-					    </tr>
-						<tr>
-						    <th><label for="lastname">Nachname</label></th>
-						    <td><input type="text" placeholder="Nachname"></td>
-					    </tr>
-						<tr>
-						    <th><label for="email">Email</label></th>
-						    <td><input type="text" placeholder="Email"></td>
-						</tr>
-						<tr>
-						    <th><label for="email">Unternehmen</label></th>
-						    <td><input type="text" placeholder="Unternehmen"></td>
-						</tr>
-					    <tr>
-							<th><label for="email">Branche</label></th>
-						    <td><input type="text" placeholder="Branche"></td>
-						</tr>
-						<tr>
-							<th><label for="email">Fachgebiete</label></th>
-						    <td><input type="text" placeholder="Fachgebiete"></td>
-						</tr>
-					</table>
-						    
-					<p><input type="submit" class="btn btn-primary" value="Update" disabled></p>   
-				</form>	      
-		    </div>
-		  </div>
-		</div>
-		
-		<!-- HEADER & FOOTER -->
-        <script src="https://transfer.hft-stuttgart.de/js/headfoot.js"></script>
-	</body>
-</html>
\ No newline at end of file
diff --git a/public/views_TBD/profile.jade b/public/views_TBD/profile.jade
deleted file mode 100644
index 6f03f645..00000000
--- a/public/views_TBD/profile.jade
+++ /dev/null
@@ -1 +0,0 @@
-include profile.html
\ No newline at end of file
-- 
GitLab


From 7217413e80193936de9d0edcaf6d3af2255714b4 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Fri, 28 Feb 2020 20:56:41 +0100
Subject: [PATCH 07/20] add DE

---
 public/js/registration.js | 3 ++-
 public/js/security.js     | 9 ++++++---
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/public/js/registration.js b/public/js/registration.js
index 1033ce3f..3e6184f9 100644
--- a/public/js/registration.js
+++ b/public/js/registration.js
@@ -22,7 +22,8 @@ $('#inputPassword').on('keyup', function () {
     isPasswordValid = checkPasswordReq($('#inputPassword').val())
     $('#passwordWarning').empty();
     if (!isPasswordValid) {
-        $('#passwordWarning').html('Must be at least 8 characters')
+        //$('#passwordWarning').html('Must be at least 8 characters')
+        $('#passwordWarning').html('Das Passwort muss mindestens 8 Zeichen haben')
     }
     switchSubmitButton()
 });
diff --git a/public/js/security.js b/public/js/security.js
index 0f4a8f09..535a95a2 100644
--- a/public/js/security.js
+++ b/public/js/security.js
@@ -6,15 +6,18 @@ $('#inputNewPwd, #inputConfirm').on('keyup', function () {
     isBest = checkPasswordReq($('#inputNewPwd').val())
     $('#recommendation').empty();
     if (!isBest) {
-        $('#recommendation').html('Must be at least 8 characters').css('color', 'red');
+        //$('#recommendation').html('Must be at least 8 characters').css('color', 'red');
+        $('#recommendation').html('Das Passwort muss mindestens 8 Zeichen haben').css('color', 'red');
     }
 
     // match or not?
     if ($('#inputNewPwd').val() == $('#inputConfirm').val()) {
-        $('#message').html('Matching').css('color', 'green');
+        //$('#message').html('Matching').css('color', 'green');
+        $('#message').html('Ãœbereinstimmend').css('color', 'green');
         isMatch = true;
     } else {
-        $('#message').html('Not Matching').css('color', 'red');
+        //$('#message').html('Not Matching').css('color', 'red');
+        $('#message').html('Nicht übereinstimmend').css('color', 'red');
         isMatch = false;
     }
     
-- 
GitLab


From 79213a949f2471ae663aa4770b5524f57bb1f32f Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Fri, 28 Feb 2020 21:01:45 +0100
Subject: [PATCH 08/20] put DE and EN pages in different folder

---
 views/{ => DE}/404.pug          |  0
 views/{ => DE}/500.pug          |  0
 views/{ => DE}/error.pug        |  0
 views/DE/forgotPwd.pug          | 56 +++++++++++++++++++
 views/DE/home.pug               | 49 +++++++++++++++++
 views/{ => DE}/layout.pug       |  0
 views/DE/profile.pug            | 94 +++++++++++++++++++++++++++++++
 views/DE/registration.pug       | 98 +++++++++++++++++++++++++++++++++
 views/DE/reset.pug              | 60 ++++++++++++++++++++
 views/DE/security.pug           | 94 +++++++++++++++++++++++++++++++
 views/DE/services.pug           | 77 ++++++++++++++++++++++++++
 views/EN/404.pug                |  4 ++
 views/EN/500.pug                |  8 +++
 views/EN/error.pug              |  6 ++
 views/{ => EN}/forgotPwd.pug    |  0
 views/{ => EN}/home.pug         |  2 +-
 views/EN/layout.pug             | 12 ++++
 views/{ => EN}/profile.pug      |  0
 views/{ => EN}/registration.pug |  0
 views/{ => EN}/reset.pug        |  0
 views/{ => EN}/security.pug     |  0
 views/{ => EN}/services.pug     |  0
 22 files changed, 559 insertions(+), 1 deletion(-)
 rename views/{ => DE}/404.pug (100%)
 rename views/{ => DE}/500.pug (100%)
 rename views/{ => DE}/error.pug (100%)
 create mode 100644 views/DE/forgotPwd.pug
 create mode 100644 views/DE/home.pug
 rename views/{ => DE}/layout.pug (100%)
 create mode 100644 views/DE/profile.pug
 create mode 100644 views/DE/registration.pug
 create mode 100644 views/DE/reset.pug
 create mode 100644 views/DE/security.pug
 create mode 100644 views/DE/services.pug
 create mode 100644 views/EN/404.pug
 create mode 100644 views/EN/500.pug
 create mode 100644 views/EN/error.pug
 rename views/{ => EN}/forgotPwd.pug (100%)
 rename views/{ => EN}/home.pug (97%)
 create mode 100644 views/EN/layout.pug
 rename views/{ => EN}/profile.pug (100%)
 rename views/{ => EN}/registration.pug (100%)
 rename views/{ => EN}/reset.pug (100%)
 rename views/{ => EN}/security.pug (100%)
 rename views/{ => EN}/services.pug (100%)

diff --git a/views/404.pug b/views/DE/404.pug
similarity index 100%
rename from views/404.pug
rename to views/DE/404.pug
diff --git a/views/500.pug b/views/DE/500.pug
similarity index 100%
rename from views/500.pug
rename to views/DE/500.pug
diff --git a/views/error.pug b/views/DE/error.pug
similarity index 100%
rename from views/error.pug
rename to views/DE/error.pug
diff --git a/views/DE/forgotPwd.pug b/views/DE/forgotPwd.pug
new file mode 100644
index 00000000..8a6b8c56
--- /dev/null
+++ b/views/DE/forgotPwd.pug
@@ -0,0 +1,56 @@
+doctype html
+html(lang="de")
+  head
+    title= "Forgot Password"
+    meta(charset="UTF-8")
+    meta(name="viewport", content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no")
+    link(rel="stylesheet", type="text/css", href="https://transfer.hft-stuttgart.de/css/bootstrap/bootstrap.css")
+    link(rel="stylesheet", type="text/css", href="https://transfer.hft-stuttgart.de/css/custom/login.css")
+    link(rel="stylesheet", href="https://use.fontawesome.com/releases/v5.8.2/css/all.css", integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay", crossorigin="anonymous")
+    style.
+        .collapse {
+            display: none;
+        }
+        .collapse.in {
+            display: block;
+        }
+        .collapsing {
+            position: relative;
+            height: 0;
+            overflow: hidden;
+            -webkit-transition-timing-function: ease;
+            -o-transition-timing-function: ease;
+            transition-timing-function: ease;
+            -webkit-transition-duration: .35s;
+            -o-transition-duration: .35s;
+            transition-duration: .35s;
+            -webkit-transition-property: height,visibility;
+            -o-transition-property: height,visibility;
+            transition-property: height,visibility;
+        }
+  body
+    div(class="container-fluid")
+        div(class="row")
+            div(class="col-md-6 offset-md-3")
+                if successes
+                    for success in successes
+                        div.alert.alert-success.alert-dismissible #{ success }
+                            a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
+                if errors
+                    for error, i in errors
+                        div.alert.alert-danger.alert-dismissible.fade.show #{ error }
+                            a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
+                form#forgotForm(class="form-signin", method="POST")
+                    img(src="https://transfer.hft-stuttgart.de/images/demo/m4lab_logo.jpg", class="img-responsive center-block", width="185", height="192")
+                    div(class="form-row")
+                        input#inputEmail(name="inputEmail", type="email", class="form-control", placeholder="E-Mail-Adresse" required)                  
+                    br
+                    input(type="submit", class="btn btn-outline-dark btn-block", value="Passwort zurücksetzen")
+
+    // jQuery
+    script(src="https://code.jquery.com/jquery-3.3.1.min.js")
+    script(src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js", integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1", crossorigin="anonymous")
+    // Bootstrap
+    script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous")
+    // M4_LAB
+    script(src="https://transfer.hft-stuttgart.de/js/headfoot.js")
diff --git a/views/DE/home.pug b/views/DE/home.pug
new file mode 100644
index 00000000..53044de1
--- /dev/null
+++ b/views/DE/home.pug
@@ -0,0 +1,49 @@
+doctype html
+html(lang="de")
+  head
+    title= "User Account"
+    meta(charset="UTF-8")
+    meta(name="viewport", content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no")
+    link(rel="stylesheet", type="text/css", href="https://transfer.hft-stuttgart.de/css/bootstrap/bootstrap.css")
+    link(rel="stylesheet", href="https://use.fontawesome.com/releases/v5.8.2/css/all.css", integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay", crossorigin="anonymous")
+    style.
+        .collapse {
+            display: none;
+        }
+        .collapse.in {
+            display: block;
+        }
+        .collapsing {
+            position: relative;
+            height: 0;
+            overflow: hidden;
+            -webkit-transition-timing-function: ease;
+            -o-transition-timing-function: ease;
+            transition-timing-function: ease;
+            -webkit-transition-duration: .35s;
+            -o-transition-duration: .35s;
+            transition-duration: .35s;
+            -webkit-transition-property: height,visibility;
+            -o-transition-property: height,visibility;
+            transition-property: height,visibility;
+        }
+  body
+    div(class="container-fluid")
+        div(class="row")
+            div(class="col-3")
+                h5
+                    span #{user.firstname} #{user.lastname}
+                div(class="nav flex-column nav-pills", id="v-pills-tab", role="tablist", aria-orientation="vertical")
+                    a(class="nav-link" href="#" aria-selected="true") Benutzerprofil
+                    a(class="nav-link" href="/account/security" aria-selected="false") Sicherheitseinstellungen
+                    a(class="nav-link" href="/account/services" aria-selected="false") Projekte und Dienste
+            div(class="col-sm-9")
+                p content goes here
+                
+    // jQuery
+    script(src="https://code.jquery.com/jquery-3.3.1.min.js")
+    script(src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js", integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1", crossorigin="anonymous")
+    // Bootstrap
+    script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous")
+    // M4_LAB
+    script(src="/js/headfootLogout.js")
\ No newline at end of file
diff --git a/views/layout.pug b/views/DE/layout.pug
similarity index 100%
rename from views/layout.pug
rename to views/DE/layout.pug
diff --git a/views/DE/profile.pug b/views/DE/profile.pug
new file mode 100644
index 00000000..9a3fc46e
--- /dev/null
+++ b/views/DE/profile.pug
@@ -0,0 +1,94 @@
+doctype html
+html(lang="de")
+  head
+    title= "User Profile"
+    meta(charset="UTF-8")
+    meta(name="viewport", content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no")
+    link(rel="stylesheet", type="text/css", href="https://transfer.hft-stuttgart.de/css/bootstrap/bootstrap.css")
+    link(rel="stylesheet", href="https://use.fontawesome.com/releases/v5.8.2/css/all.css", integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay", crossorigin="anonymous")
+    style.
+        .collapse {
+            display: none;
+        }
+        .collapse.in {
+            display: block;
+        }
+        .collapsing {
+            position: relative;
+            height: 0;
+            overflow: hidden;
+            -webkit-transition-timing-function: ease;
+            -o-transition-timing-function: ease;
+            transition-timing-function: ease;
+            -webkit-transition-duration: .35s;
+            -o-transition-duration: .35s;
+            transition-duration: .35s;
+            -webkit-transition-property: height,visibility;
+            -o-transition-property: height,visibility;
+            transition-property: height,visibility;
+        }
+  body
+    div(class="container-fluid")
+        div(class="row")
+            div(class="col-3")
+                h5
+                    span #{user.firstname} #{user.lastname}
+                div(class="nav flex-column nav-pills", id="v-pills-tab", role="tablist", aria-orientation="vertical")
+                    a(class="nav-link" href="#" aria-selected="true") Benutzerprofil
+                    a(class="nav-link" href="/account/security" aria-selected="false") Sicherheitseinstellungen
+                    a(class="nav-link" href="/account/services" aria-selected="false") Projekte und Dienste
+            div(class="col-sm-9")
+                if successes
+                    for success in successes
+                        div.alert.alert-success.alert-dismissible #{ success }
+                            a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
+                if errors
+                    for error, i in errors
+                        div.alert.alert-danger.alert-dismissible.fade.show #{ error }
+                            a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
+                form#profileForm(method="POST", action="/updateProfile")
+                    div(class="form-row")
+                        div(class='form-group col-md-2')
+                            label(for="title") Titel
+                            select#inputTitle(name="inputTitle", class="form-control", value=user.title)
+                                option(value="Prof.") Prof.
+                                option(value="Dr.") Dr.
+                                option(value="Dipl.-Ing.") Dipl.-Ing.
+                                option(value="etc.") etc.
+                                script.
+                                    var titleOptions = document.getElementById('inputTitle').options;
+                                    for (i=0; i < titleOptions.length; i++) {
+                                        if (titleOptions[i].value == '#{user.title}')
+                                            titleOptions[i].selected = true;
+                                    }
+                        div(class='form-group col-md-3')
+                            label(for="firstname") Vorname
+                            input#inputFirstname(name="inputFirstname", type="text", class="form-control", placeholder="Vorname", value=user.firstname required)
+                        div(class='form-group col-md-3')
+                            label(for="lastname") Nachname
+                            input#inputLastname(name="inputLastname", type="text", class="form-control", placeholder="Nachname", value=user.lastname required)
+                    div(class="form-row")
+                        div(class='form-group col-md-8')
+                            label(for="email") Email
+                            input#inputEmail(name="inputEmail", type="email", class="form-control", placeholder="Email", value=email required)
+                    div(class="form-row")
+                        div(class='form-group col-md-8')
+                            label(for="organisation") Unternehmen
+                            input#inputOrganisation(name="inputOrganisation", type="text", class="form-control", placeholder="Unternehmen", value=user.organisation)
+                    div(class="form-row")
+                        div(class='form-group col-md-8')
+                            label(for="industry") Branche
+                            input#inputIndustry(name="inputIndustry", type="text", class="form-control", placeholder="Branche", value=user.industry)
+                    div(class="form-row")
+                        div(class='form-group col-md-8')
+                            label(for="speciality") Fachgebiete
+                            input#inputSpeciality(name="inputSpeciality", type="text", class="form-control", placeholder="Fachgebiete", value=user.speciality)                    
+                    input(type="submit", class="btn btn-primary", value="Update")
+
+    // jQuery
+    script(src="https://code.jquery.com/jquery-3.3.1.min.js")
+    script(src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js", integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1", crossorigin="anonymous")
+    // Bootstrap
+    script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous")
+    // M4_LAB
+    script(src="/js/headfootLogout.js")
\ No newline at end of file
diff --git a/views/DE/registration.pug b/views/DE/registration.pug
new file mode 100644
index 00000000..d4be0c07
--- /dev/null
+++ b/views/DE/registration.pug
@@ -0,0 +1,98 @@
+doctype html
+html(lang="de")
+  head
+    title= "Create New Account"
+    meta(charset="UTF-8")
+    meta(name="viewport", content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no")
+    link(rel="stylesheet", type="text/css", href="https://transfer.hft-stuttgart.de/css/bootstrap/bootstrap.css")
+    link(rel="stylesheet", href="https://use.fontawesome.com/releases/v5.8.2/css/all.css", integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay", crossorigin="anonymous")
+    style.
+        .collapse {
+            display: none;
+        }
+        .collapse.in {
+            display: block;
+        }
+        .collapsing {
+            position: relative;
+            height: 0;
+            overflow: hidden;
+            -webkit-transition-timing-function: ease;
+            -o-transition-timing-function: ease;
+            transition-timing-function: ease;
+            -webkit-transition-duration: .35s;
+            -o-transition-duration: .35s;
+            transition-duration: .35s;
+            -webkit-transition-property: height,visibility;
+            -o-transition-property: height,visibility;
+            transition-property: height,visibility;
+        }
+        .warning {
+            color: red;
+            font-size: 11px;
+        }
+  body
+    div(class="container-fluid")
+        div(class="row")
+            div(class="col-md-6 offset-md-2")
+                h3(class="mb-3 font-weight-bold") Neues Benutzerkonto anlegen
+            div(class="col-md-6 offset-md-3")
+                if successes
+                    for success in successes
+                        div.alert.alert-success.alert-dismissible #{ success }
+                            a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
+                if errors
+                    for error, i in errors
+                        div.alert.alert-danger.alert-dismissible.fade.show #{ error }
+                            a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
+                form(method="POST")
+                    h5(class="mb-3 font-weight-bold") Anmeldedaten
+                    div(class='form-row')
+                        div(class='form-group col-md-6')
+                            input#inputEmail(name="inputEmail", type="email", class="form-control", placeholder="E-Mail-Adresse*" required)
+                            span#emailWarning(class='warning')
+                        div(class="form-group col-md-6")
+                            input#inputPassword(name="inputPassword", type="password", class="form-control", data-toggle="password", placeholder="Passwort*" required)
+                            span#passwordWarning(class='warning')
+                    h5(class="mb-3 font-weight-bold") Benutzerprofil
+                    div(class="form-row")
+                        div(class='form-group col-md-2')
+                            select#inputSalutation(name="inputSalutation", class="form-control")
+                                option(value="") - Anrede -
+                                option(value="Herr") Herr
+                                option(value="Frau") Frau
+                                option(value="Divers") Divers
+                        div(class='form-group col-md-2')
+                            select#inputTitle(name="inputTitle", class="form-control")
+                                option(value="") - Titel -
+                                option(value="Prof.") Prof.
+                                option(value="Dr.") Dr.
+                                option(value="Dipl.-Ing.") Dipl.-Ing.
+                                option(value="etc.") etc.
+                        div(class='form-group col-md-4')
+                            input#inputFirstname(name="inputFirstname", type="text", class="form-control", placeholder="Vorname*" required)
+                        div(class='form-group col-md-4')
+                            input#inputLastname(name="inputLastname", type="text", class="form-control", placeholder="Nachname*" required)
+                    div(class="form-group")
+                        input#inputOrganisation(name="inputOrganisation", type="text", class="form-control", placeholder="Unternehmen")
+                    div(class="form-group")
+                        input#inputIndustry(name="inputIndustry", type="text", class="form-control", placeholder="Branche")
+                    div(class="form-group")
+                        input#inputSpeciality(name="inputSpeciality", type="text", class="form-control", placeholder="Fachgebiete")
+                    p <em><small>* Pflichtfeld</small></em>
+                    input#submitBtn(type="submit", class="btn btn-outline-dark btn-block", value="Senden" disabled)
+                br
+                p(class="text-center") Sie haben bereits ein Benutzerkonto? <a href="/">Melden Sie sich hier an</a>.
+                    
+
+    // jQuery
+    script(src="https://code.jquery.com/jquery-3.3.1.min.js")
+    script(src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js", integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1", crossorigin="anonymous")
+    // Bootstrap
+    script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous")
+    // toggle password
+    script(src='https://unpkg.com/bootstrap-show-password@1.2.1/dist/bootstrap-show-password.min.js')
+    // M4_LAB
+    script(src="/js/generalFunction.js")
+    script(src="/js/registration.js")
+    script(src="https://transfer.hft-stuttgart.de/js/headfoot.js")
\ No newline at end of file
diff --git a/views/DE/reset.pug b/views/DE/reset.pug
new file mode 100644
index 00000000..8f2d8f4c
--- /dev/null
+++ b/views/DE/reset.pug
@@ -0,0 +1,60 @@
+doctype html
+html(lang="de")
+  head
+    title= "Reset Password"
+    meta(charset="UTF-8")
+    meta(name="viewport", content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no")
+    link(rel="stylesheet", type="text/css", href="https://transfer.hft-stuttgart.de/css/bootstrap/bootstrap.css")
+    link(rel="stylesheet", type="text/css", href="https://transfer.hft-stuttgart.de/css/custom/login.css")
+    link(rel="stylesheet", href="https://use.fontawesome.com/releases/v5.8.2/css/all.css", integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay", crossorigin="anonymous")
+    style.
+        .collapse {
+            display: none;
+        }
+        .collapse.in {
+            display: block;
+        }
+        .collapsing {
+            position: relative;
+            height: 0;
+            overflow: hidden;
+            -webkit-transition-timing-function: ease;
+            -o-transition-timing-function: ease;
+            transition-timing-function: ease;
+            -webkit-transition-duration: .35s;
+            -o-transition-duration: .35s;
+            transition-duration: .35s;
+            -webkit-transition-property: height,visibility;
+            -o-transition-property: height,visibility;
+            transition-property: height,visibility;
+        }
+  body
+    div(class="container-fluid")
+        div(class="row")
+            div(class="col-md-6 offset-md-3")
+                if successes
+                    for success in successes
+                        div.alert.alert-success.alert-dismissible #{ success }
+                            a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
+                if errors
+                    for error, i in errors
+                        div.alert.alert-danger.alert-dismissible.fade.show #{ error }
+                            a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
+                form#forgotForm(method="POST", class="form-signin")
+                    img(src="https://transfer.hft-stuttgart.de/images/demo/m4lab_logo.jpg", class="img-responsive center-block", width="185", height="192")
+                    div(class="form-row")
+                        input#inputNewPwd(name="inputNewPwd", type="password", class="form-control", placeholder="Neues Passwort" required)
+                        span#recommendation(class='warning')
+                        input#inputConfirm(name="inputConfirm", type="password", class="form-control", placeholder="Passwort bestätigen" required)
+                        span#message(class='warning')
+                    input#updateBtn(type="submit", class="btn btn-outline-dark btn-block", value="Passwort ändern" disabled)
+
+    // jQuery
+    script(src="https://code.jquery.com/jquery-3.3.1.min.js")
+    script(src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js", integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1", crossorigin="anonymous")
+    // Bootstrap
+    script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous")
+    // M4_LAB
+    script(src="/js/security.js")
+    script(src="/js/generalFunction.js")
+    script(src="https://transfer.hft-stuttgart.de/js/headfoot.js")
diff --git a/views/DE/security.pug b/views/DE/security.pug
new file mode 100644
index 00000000..5d4a214a
--- /dev/null
+++ b/views/DE/security.pug
@@ -0,0 +1,94 @@
+doctype html
+html(lang="de")
+  head
+    title= "User Profile"
+    meta(charset="UTF-8")
+    meta(name="viewport", content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no")
+    link(rel="stylesheet", type="text/css", href="https://transfer.hft-stuttgart.de/css/bootstrap/bootstrap.css")
+    link(rel="stylesheet", href="https://use.fontawesome.com/releases/v5.8.2/css/all.css", integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay", crossorigin="anonymous")
+    style.
+        .collapse {
+            display: none;
+        }
+        .collapse.in {
+            display: block;
+        }
+        .collapsing {
+            position: relative;
+            height: 0;
+            overflow: hidden;
+            -webkit-transition-timing-function: ease;
+            -o-transition-timing-function: ease;
+            transition-timing-function: ease;
+            -webkit-transition-duration: .35s;
+            -o-transition-duration: .35s;
+            transition-duration: .35s;
+            -webkit-transition-property: height,visibility;
+            -o-transition-property: height,visibility;
+            transition-property: height,visibility;
+        }
+        .warning {
+            font-size: 11px;
+        }
+  body
+    div(class="container-fluid")
+        div(class="row")
+            div(class="col-3")
+                h5
+                    span #{user.firstName} #{user.lastName}
+                div(class="nav flex-column nav-pills", id="v-pills-tab", role="tablist", aria-orientation="vertical")
+                    a(class="nav-link" href="/account/profile" aria-selected="true") Benutzerprofil
+                    a(class="nav-link" href="#" aria-selected="false") Sicherheitseinstellungen
+                    a(class="nav-link" href="/account/services" aria-selected="false") Projekte und Dienste
+            div(class="col-sm-9")
+                if successes
+                    for success in successes
+                        div.alert.alert-success.alert-dismissible #{ success }
+                            a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
+                if errors
+                    for error, i in errors
+                        div.alert.alert-danger.alert-dismissible.fade.show #{ error }
+                            a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
+                form(class="needs-validation", method="post", action="/account/changePwd" novalidate)
+                    div(class="form-group row")
+                        label(for="currPwd") Aktuelles Passwort
+                        input(id="inputCurrPwd", name="inputCurrPwd", type="password", class="form-control" required)
+                        div(class="invalid-feedback") Please fill in this field.
+                    div(class="form-group row")
+                        label(for="newPwd") Neues Passwort
+                        input#inputNewPwd(name="inputNewPwd", type="password", class="form-control" required)
+                        span#recommendation
+                        div(class="invalid-feedback") Please fill in this field.
+                    div(class="form-group row")
+                        label(for="confirm") Bestätigen Sie das neue Passwort
+                        input#inputConfirm(name="inputConfirm", type="password", class="form-control" required)
+                        span#message
+                        div(class="invalid-feedback") Please fill in this field.
+                    input#updateBtn(type="submit", class="btn btn-primary", value="Update Password" disabled)
+                    
+    // jQuery
+    script(src="https://code.jquery.com/jquery-3.3.1.min.js")
+    script(src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js", integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1", crossorigin="anonymous")
+    // Bootstrap
+    script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous")
+    // M4_LAB
+    script(src="/js/security.js")
+    script(src="/js/generalFunction.js")
+    script(src="/js/headfootLogout.js")
+    script.
+        // check input fields
+        'use strict';
+        window.addEventListener('load', function() {
+            // Fetch all the forms we want to apply custom Bootstrap validation styles to
+            var forms = document.getElementsByClassName('needs-validation');
+            // Loop over them and prevent submission
+            var validation = Array.prototype.filter.call(forms, function(form) {
+                form.addEventListener('submit', function(event) {
+                    if (form.checkValidity() === false) {
+                        event.preventDefault();
+                        event.stopPropagation();
+                    }
+                    form.classList.add('was-validated');
+                }, false);
+            });
+        }, false);
diff --git a/views/DE/services.pug b/views/DE/services.pug
new file mode 100644
index 00000000..6ab101f3
--- /dev/null
+++ b/views/DE/services.pug
@@ -0,0 +1,77 @@
+doctype html
+html(lang="de")
+  head
+    title= "User Profile"
+    meta(charset="UTF-8")
+    meta(name="viewport", content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no")
+    link(rel="stylesheet", type="text/css", href="https://transfer.hft-stuttgart.de/css/bootstrap/bootstrap.css")
+    link(rel="stylesheet", href="https://use.fontawesome.com/releases/v5.8.2/css/all.css", integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay", crossorigin="anonymous")
+    style.
+        .collapse {
+            display: none;
+        }
+        .collapse.in {
+            display: block;
+        }
+        .collapsing {
+            position: relative;
+            height: 0;
+            overflow: hidden;
+            -webkit-transition-timing-function: ease;
+            -o-transition-timing-function: ease;
+            transition-timing-function: ease;
+            -webkit-transition-duration: .35s;
+            -o-transition-duration: .35s;
+            transition-duration: .35s;
+            -webkit-transition-property: height,visibility;
+            -o-transition-property: height,visibility;
+            transition-property: height,visibility;
+        }
+  body
+    div(class="container-fluid")
+        div(class="row")
+            div(class="col-3")
+                h5
+                    span #{user.firstName} #{user.lastName}
+                div(class="nav flex-column nav-pills", id="v-pills-tab", role="tablist", aria-orientation="vertical")
+                    a(class="nav-link" href="/account/profile" aria-selected="true") Benutzerprofil
+                    a(class="nav-link" href="/account/security" aria-selected="false") Sicherheitseinstellungen
+                    a(class="nav-link" href="#" aria-selected="false") Projekte und Dienste
+            div(class="col-sm-9")
+                if successes
+                    for success in successes
+                        div.alert.alert-success.alert-dismissible #{ success }
+                            a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
+                if errors
+                    for error, i in errors
+                        div.alert.alert-danger.alert-dismissible.fade.show #{ error }
+                            a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
+                table
+                    for item in project
+                        tr
+                            td <strong>#{item.title}</strong>
+                            if item.userStatus
+                                td
+                                    button(type="button", class="btn btn-secondary", onclick="unsubscribe()") Projektbeteiligung beenden
+                            else
+                                td
+                                    button(type="button", class="btn btn-success", onclick="subscribe()") Am Projekt beteiligen
+                        tr
+                            td(colspan="2") #{item.summary}
+                        tr
+                            td(colspan="2") <i>Ansprechpartner: #{item.cp}</i>
+                    
+    // jQuery
+    script(src="https://code.jquery.com/jquery-3.3.1.min.js")
+    script(src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js", integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1", crossorigin="anonymous")
+    // Bootstrap
+    script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous")
+    // M4_LAB
+    script(src="/js/headfootLogout.js")
+    script.
+        function subscribe() {
+            alert("To be implemented: Ihre Anfrage wird an den zuständigen Projektleiter gesendet.")
+        }
+        function unsubscribe() {
+            alert("To be implemented: Ihre Projektbeteiligung wurde beendet und der zuständige Projektleiter in Kenntnis gesetzt.")
+        }
\ No newline at end of file
diff --git a/views/EN/404.pug b/views/EN/404.pug
new file mode 100644
index 00000000..dc9e0a8c
--- /dev/null
+++ b/views/EN/404.pug
@@ -0,0 +1,4 @@
+extends error
+
+block content
+  h2 Cannot find #{url}
\ No newline at end of file
diff --git a/views/EN/500.pug b/views/EN/500.pug
new file mode 100644
index 00000000..cbc47e79
--- /dev/null
+++ b/views/EN/500.pug
@@ -0,0 +1,8 @@
+extends error
+
+block content
+  h1 Error: #{error.message}
+  if settings['verbose errors']
+    pre= error.stack
+  else
+    p An error ocurred!
\ No newline at end of file
diff --git a/views/EN/error.pug b/views/EN/error.pug
new file mode 100644
index 00000000..bf750c00
--- /dev/null
+++ b/views/EN/error.pug
@@ -0,0 +1,6 @@
+html
+  head 
+    title Error
+  body
+    h1 An error occurred!
+    block content
\ No newline at end of file
diff --git a/views/forgotPwd.pug b/views/EN/forgotPwd.pug
similarity index 100%
rename from views/forgotPwd.pug
rename to views/EN/forgotPwd.pug
diff --git a/views/home.pug b/views/EN/home.pug
similarity index 97%
rename from views/home.pug
rename to views/EN/home.pug
index cea90b4e..050c1bf9 100644
--- a/views/home.pug
+++ b/views/EN/home.pug
@@ -34,7 +34,7 @@ html(lang="en")
                 h5
                     span #{greeting}
                 div(class="nav flex-column nav-pills", id="v-pills-tab", role="tablist", aria-orientation="vertical")
-                    a(class="nav-link" href="#" aria-selected="true") Profile
+                    a(class="nav-link" href="#" aria-selected="true") #{i18n.__(Profile)}
                     a(class="nav-link" href="/account/security" aria-selected="false") Security
                     a(class="nav-link" href="/account/services" aria-selected="false") Services
             div(class="col-sm-9")
diff --git a/views/EN/layout.pug b/views/EN/layout.pug
new file mode 100644
index 00000000..32d27e01
--- /dev/null
+++ b/views/EN/layout.pug
@@ -0,0 +1,12 @@
+doctype html
+html
+    head
+        title PassportJS SAML example
+        block links
+            link(rel='stylesheet', href='bower_components/bootstrap/dist/css/bootstrap.css')
+    body
+        div.container
+            block content
+        script(src='bower_components/jquery/dist/jquery.min.js')
+        script(src='bower_components/bootstrap/dist/js/bootstrap.min.js')
+        block scripts
diff --git a/views/profile.pug b/views/EN/profile.pug
similarity index 100%
rename from views/profile.pug
rename to views/EN/profile.pug
diff --git a/views/registration.pug b/views/EN/registration.pug
similarity index 100%
rename from views/registration.pug
rename to views/EN/registration.pug
diff --git a/views/reset.pug b/views/EN/reset.pug
similarity index 100%
rename from views/reset.pug
rename to views/EN/reset.pug
diff --git a/views/security.pug b/views/EN/security.pug
similarity index 100%
rename from views/security.pug
rename to views/EN/security.pug
diff --git a/views/services.pug b/views/EN/services.pug
similarity index 100%
rename from views/services.pug
rename to views/EN/services.pug
-- 
GitLab


From fcf95f417f3cfad33746b933709841952b6cf65a Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Fri, 28 Feb 2020 21:24:24 +0100
Subject: [PATCH 09/20] update wordings

---
 views/DE/registration.pug | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/views/DE/registration.pug b/views/DE/registration.pug
index d4be0c07..f5e9973e 100644
--- a/views/DE/registration.pug
+++ b/views/DE/registration.pug
@@ -82,7 +82,7 @@ html(lang="de")
                     p <em><small>* Pflichtfeld</small></em>
                     input#submitBtn(type="submit", class="btn btn-outline-dark btn-block", value="Senden" disabled)
                 br
-                p(class="text-center") Sie haben bereits ein Benutzerkonto? <a href="/">Melden Sie sich hier an</a>.
+                p(class="text-center") Sie haben bereits ein Benutzerkonto? <a href="/account">Melden Sie sich hier an</a>.
                     
 
     // jQuery
-- 
GitLab


From dfe9016498d3812dfb66324ceeb90f359f914f72 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Wed, 4 Mar 2020 13:55:41 +0100
Subject: [PATCH 10/20] add salutation to user table

---
 database/alter.sql | 4 ++++
 1 file changed, 4 insertions(+)
 create mode 100644 database/alter.sql

diff --git a/database/alter.sql b/database/alter.sql
new file mode 100644
index 00000000..80d0ad77
--- /dev/null
+++ b/database/alter.sql
@@ -0,0 +1,4 @@
+// add `salutation` column and alter `title` to be not mandatory
+ALTER TABLE `userdb`.`user` 
+ADD COLUMN `salutation` VARCHAR(45) NULL DEFAULT NULL AFTER `email`,
+CHANGE COLUMN `title` `title` VARCHAR(45) NULL DEFAULT NULL ;
\ No newline at end of file
-- 
GitLab


From 198aca69f4cfbb54eedd7d8003c800ec452c9e95 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Wed, 4 Mar 2020 13:56:35 +0100
Subject: [PATCH 11/20] get user's salutation

---
 routes/methods.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/routes/methods.js b/routes/methods.js
index 3f3edf54..5a7dc652 100644
--- a/routes/methods.js
+++ b/routes/methods.js
@@ -57,7 +57,7 @@ var methods = {
         })
     },
     getUserByEmail: function(email, callback) {
-        dbconn.user.query('SELECT title, firstname, lastname, industry, organisation, speciality FROM user WHERE email = "' +email+'"', function (err, rows, fields) {
+        dbconn.user.query('SELECT salutation, title, firstname, lastname, industry, organisation, speciality FROM user WHERE email = "' +email+'"', function (err, rows, fields) {
             if (err) {
                 throw err;
             }
-- 
GitLab


From ca5d01c5c589566c2e78b328dac22a706d9179e2 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Wed, 4 Mar 2020 13:58:23 +0100
Subject: [PATCH 12/20] DE

---
 routes/routes.js          | 149 ++++++++++++++++++++++----------------
 views/DE/home.pug         |   6 +-
 views/DE/profile.pug      |  26 +++++--
 views/DE/registration.pug |   2 +-
 views/DE/security.pug     |  12 +--
 views/DE/services.pug     |   4 +-
 6 files changed, 118 insertions(+), 81 deletions(-)

diff --git a/routes/routes.js b/routes/routes.js
index c55b88e1..09d5fe6b 100644
--- a/routes/routes.js
+++ b/routes/routes.js
@@ -96,11 +96,15 @@ module.exports = function (app, config, passport, i18n) {
     text: ""
   };
 
-  var updatePasswordMailContent = "Hello,\n\n"+
-    "We would like to notify that your password has been successfully updated.\n\n"+
-    "Thanks,\nM4_LAB Team"
-  var updatePasswordMailSubject = "Your M4_LAB Password has been updated"
-
+  var updatePasswordMailSubject = "Ihr Passwort für das Transferportal wurde gespeichert."
+  var mailSignature = "Mit den besten Grüßen,\ndas Transferportal-Team der HFT Stuttgart\n\n"+
+    "Transferportal der Hochschule für Technik Stuttgart\n"+
+    "Schellingstr. 24\n"+
+    "70174 Stuttgart\n"+
+    "m4lab@hft-stuttgart.de\n"+
+    "https://transfer.hft-stuttgart.de"
+  var updatePasswordMailContent = "Lieber Nutzer,\n\n"+"Ihr Passwort wurde erfolgreich geändert.\n\n"+mailSignature
+  
   // ================ test i18n ==================
   i18n.setLocale('de');
   app.get('/de', function(req, res) {
@@ -108,30 +112,32 @@ module.exports = function (app, config, passport, i18n) {
     res.send(greeting)
   });
   
+  var lang = 'DE'
+
   // ======== APP ROUTES ====================
-  app.get('/account', function (req, res) {
+  app.get('/', function (req, res) {
     if (req.isAuthenticated()) {
       methods.getUserByEmail(req.user.email, function(data, err){
         if (!err) {
-          res.render('home', {
-            greeting: i18n.__('Hello'),
+          res.render(lang+'/home', {
+            user: data
           });
         }
       })
     } else {
-      res.redirect('/account/login');
-    }
+      res.redirect('/login'); // localhost
+    } 
   });
 
   app.get('/error', function (req, res) {
-    res.render('error')
+    res.render(lang+'/error')
   });
 
-  app.get('/account/login',
+  app.get('/login',
     passport.authenticate(config.passport.strategy,
       {
-        successRedirect: '/account/',
-        failureRedirect: '/account/login'
+        successRedirect: '/',
+        failureRedirect: '/login'
       })
   );
 
@@ -157,22 +163,22 @@ module.exports = function (app, config, passport, i18n) {
     });
   });
 
-  app.get('/account/profile', function (req, res) {
+  app.get('/profile', function (req, res) {
     if (req.isAuthenticated()) {
       methods.getUserByEmail(req.user.email, function(data, err){
         if (!err) {
-          res.render('profile', {
+          res.render(lang+'/profile', {
             user: data,
             email: req.user.email
           });
         }
       })
     } else {
-      res.redirect('/account/login');
+      res.redirect('/login');
     }
   });
 
-  app.get('/account/services', function (req, res) {
+  app.get('/services', function (req, res) {
     if (req.isAuthenticated()) {
       async.waterfall([
         // get userId by email from userdb
@@ -225,29 +231,30 @@ module.exports = function (app, config, passport, i18n) {
           }
 
           // render the page
-          res.render('services', {
+          res.render(lang+'/services', {
             user: req.user,
             project: allProjects
           });
         }
       ])
     } else {
-      res.redirect('/account/login');
+      res.redirect('/login');
     }
   });
 
-  app.get('/account/security', function (req, res) {
+  app.get('/security', function (req, res) {
     if (req.isAuthenticated()) {
-      res.render('security', {
+      res.render(lang+'/security', {
         user: req.user // useful for view engine, useless for HTML
       });
     } else {
-      res.redirect('/account/login');
+      res.redirect('/login');
     }
   });
 
   app.post('/updateProfile', function (req, res) {
     var userData = {
+      salutation: req.body.inputSalutation,
       title: req.body.inputTitle,
       firstname: req.body.inputFirstname,
       lastname: req.body.inputLastname,
@@ -267,11 +274,11 @@ module.exports = function (app, config, passport, i18n) {
             else {
               req.flash('success', 'Profile updated!');
             }
-            res.redirect('/account/profile');
+            res.redirect('/profile');
         })
       }
     } else {
-      res.redirect('/account/login');
+      res.redirect('/login');
     }
   });
   
@@ -286,7 +293,7 @@ module.exports = function (app, config, passport, i18n) {
           // Load hashed passwd from DB
           dbconn.user.query('SELECT password FROM credential WHERE user_id='+userId, function (err, rows, fields) {
             if (err) {
-              res.redirect('/account/500')
+              res.redirect('/500')
               throw err
             }
             var userPwd = rows[0].password
@@ -294,17 +301,21 @@ module.exports = function (app, config, passport, i18n) {
             // check if the password is correct
             bcrypt.compare(currPwd, userPwd, function(err, isMatch) {
               if (err) {
-                res.redirect('/account/500')
+                res.redirect('/500')
                 throw err
               }
               else if (!isMatch) {
-                req.flash('error', "Sorry, your password was incorrect. Please double-check your password.")
-                res.redirect('/account/security')
+                //req.flash('error', "Sorry, your password was incorrect. Please double-check your password.")
+                req.flash('error', "Das Passwort ist leider falsch. Bitte überprüfen Sie Ihre Eingabe.")
+                //res.redirect('/account/security')
+                res.redirect('/security')
               }
               else {
                 if ( newPwd != retypePwd ) {
+                  //req.flash('error', "Passwords do no match. Please make sure you re-type your new password correctly.")
                   req.flash('error', "Passwords do no match. Please make sure you re-type your new password correctly.")
-                  res.redirect('/account/security')
+                  //res.redirect('/account/security')
+                  res.redirect('/security')
                 }
                 else {
                   // update password
@@ -316,13 +327,16 @@ module.exports = function (app, config, passport, i18n) {
                       }
                       methods.updateCredential(credentialData, function(err){
                         if (err) {
-                          req.flash('error', "Database error: Password cannot be modified.")
+                          //req.flash('error', "Database error: Password cannot be modified.")
+                          req.flash('error', "Datenbankfehler: Passwort kann nicht geändert werden.")
                           throw err
                         }
                         else {
-                          req.flash('success', "Pasword updated!")
+                          //req.flash('success', "Pasword updated!")
+                          req.flash('success', "Passwort aktualisiert!")
                           mailOptions.to = req.user.email
-                          mailOptions.subject = "Your M4_LAB Password has been updated"
+                          //mailOptions.subject = "Your M4_LAB Password has been updated."
+                          mailOptions.subject = updatePasswordMailSubject
                           mailOptions.text = updatePasswordMailContent
                           smtpTransport.sendMail(mailOptions, function(err) {
                             if (err) {
@@ -330,7 +344,8 @@ module.exports = function (app, config, passport, i18n) {
                             }
                           });
                         }
-                        res.redirect('/account/security')
+                        //res.redirect('/account/security')
+                        res.redirect('/security')
                       })
                     });
                   });
@@ -342,12 +357,12 @@ module.exports = function (app, config, passport, i18n) {
       })  
     }
     else {
-      res.redirect('/account/login');
+      res.redirect('/login');
     }
   });
 
   app.get('/forgotPwd', function (req, res) {
-    res.render('forgotPwd', {
+    res.render(lang+'/forgotPwd', {
       user: req.user
     });
   });
@@ -372,13 +387,19 @@ module.exports = function (app, config, passport, i18n) {
         methods.checkUserEmail(emailAddress, function(err, user){
           if (user) {
             console.log("email: user found");
-            var emailSubject = "M4_LAB Password Reset";
-            var emailContent = "Hi User,\n\n"+
+            //var emailSubject = "M4_LAB Password Reset";
+            var emailSubject = "Ihre Passwort-Anfrage an das Transferportal der HFT Stuttgart";
+            /* var emailContent = "Hi User,\n\n"+
               "we've received a request to reset your password. If you didn't make the request, just ignore this email.\n\n"+
               "Otherwise, you can reset your password using this link: http://m4lab.hft-stuttgart.de/account/reset/" + token + "\n" +
               "This password reset is only valid for 1 hour.\n\n"+
-              "Thanks,\nM4_LAB Team"
-            
+              "Thanks,\nM4_LAB Team" */
+            var emailContent = "Lieber Nutzer,\n\n"+
+              "wir haben Ihre Anfrage zur Erneuerung Ihres Passwortes erhalten. Falls Sie diese Anfrage nicht gesendet haben, ignorieren Sie bitte diese E-Mail.\n\n"+
+              //"Sie können Ihr Passwort mit dem Klick auf diesen Link ändern: http://m4lab.hft-stuttgart.de/account/reset/" + token + "\n" + // test server
+              "Sie können Ihr Passwort mit dem Klick auf diesen Link ändern: http://localhost:9989/reset/" + token + "\n" + // localhost
+              "Dieser Link ist aus Sicherheitsgründen nur für 1 Stunde gültig.\n\n"+mailSignature
+
             var credentialData = {
               user_id: user.id,
               resetPasswordToken: token,
@@ -402,34 +423,30 @@ module.exports = function (app, config, passport, i18n) {
           }
         });
       }
-      /*,
-      function(token, user, done) {
-        mailOptions.to = emailAddress;
-        mailOptions.subject = emailSubject;
-        mailOptions.text = emailContent;
-        smtpTransport.sendMail(mailOptions, function(err) {
-          done(err, 'done');
-        });
-      } */
     ], function(err) {
       if (err) {
-        req.flash('error', 'An error occured. Please try again.');
+        //req.flash('error', 'An error occured. Please try again.');
+        req.flash('error', 'Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.');
       }
       else {
-        req.flash('success', 'If your email is registered, an e-mail has been sent to ' + emailAddress + ' with further instructions.');
+        //req.flash('success', 'If your email is registered, an e-mail has been sent to ' + emailAddress + ' with further instructions.');
+        req.flash('success', 'Wenn Ihre E-Mail-Adresse registriert ist, wurde eine E-Mail mit dem weiteren Vorgehen an ' + emailAddress + ' versendet.');
       }
-      res.redirect('/account/forgotPwd');
+      //res.redirect('/account/forgotPwd'); // deployment
+      res.redirect('/forgotPwd'); // localhost
     });
   });
 
   app.get('/reset/:token', function(req, res) {
     methods.getUserByToken(req.params.token, function(err, user){
       if (!user) {
-        req.flash('error', 'Password reset token is invalid or has expired.');
-        res.redirect('/account/forgotPwd');
+        //req.flash('error', 'Password reset token is invalid or has expired.');
+        req.flash('error', 'Der Schlüssel zum zurücksetzen des Passworts ist ungültig oder abgelaufen.');
+        //res.redirect('/account/forgotPwd'); // deployment
+        res.redirect('/forgotPwd'); // localhost
       }
       else {
-        res.render('reset');
+        res.render(lang+'/reset');
       }
     });
   });
@@ -448,11 +465,13 @@ module.exports = function (app, config, passport, i18n) {
             // update password
             methods.updateCredential(credentialData, function(err){
               if (err) {
-                req.flash('error', "Database error: Password cannot be modified.")
+                //req.flash('error', "Database error: Password cannot be modified.")
+                req.flash('error', "Datenbankfehler: Passwort kann nicht geändert werden.")
                 throw err
               }
               else {
-                req.flash('success', "Your pasword has been updated.")
+                //req.flash('success', "Your pasword has been updated.")
+                req.flash('success', "Passwort aktualisiert!")
                 // send notifiaction email
                 mailOptions.to = user.email
                 mailOptions.subject = updatePasswordMailSubject
@@ -463,7 +482,7 @@ module.exports = function (app, config, passport, i18n) {
                   }
                 });
                 // redirect to login page
-                res.redirect('/account/login')
+                res.redirect('/login')
               }
             })
           });
@@ -471,7 +490,7 @@ module.exports = function (app, config, passport, i18n) {
       }
       else {
         req.flash('error', "User not found.")
-        res.redirect('/account/login')
+        res.redirect('/login')
       }
     });
    
@@ -479,7 +498,7 @@ module.exports = function (app, config, passport, i18n) {
 
   // todo: user registration with captcha
   app.get('/registration', function(req, res) {
-    res.render('registration')
+    res.render(lang+'/registration')
   })
 
   app.post('/registration', function(req, res) {
@@ -490,6 +509,7 @@ module.exports = function (app, config, passport, i18n) {
     // user data
     var curDate = new Date()
     var userData = {
+      salutation: req.body.inputSalutation,
       title: req.body.inputTitle,
       firstname: req.body.inputFirstname,
       lastname: req.body.inputLastname,
@@ -509,12 +529,15 @@ module.exports = function (app, config, passport, i18n) {
         }
         methods.registerNewUser(newAccount, function(err){
           if (err) {
-            req.flash('error', "Failed");
+            //req.flash('error', "Failed")
+            req.flash('error', "Fehlgeschlagen")
           }
           else {
-            req.flash('success', 'Your account has been created. Please log in.');
+            //req.flash('success', 'Your account has been created. Please log in.')
+            req.flash('success', 'Ihr Benutzerkonto wurde angelegt. Bitte melden Sie sich an.') 
           }
-          res.redirect('/account/registration');
+          //res.redirect('/account/registration'); // deployment
+          res.redirect('/registration'); // localhost
         })
       });
     });
diff --git a/views/DE/home.pug b/views/DE/home.pug
index 53044de1..58b2427c 100644
--- a/views/DE/home.pug
+++ b/views/DE/home.pug
@@ -34,9 +34,9 @@ html(lang="de")
                 h5
                     span #{user.firstname} #{user.lastname}
                 div(class="nav flex-column nav-pills", id="v-pills-tab", role="tablist", aria-orientation="vertical")
-                    a(class="nav-link" href="#" aria-selected="true") Benutzerprofil
-                    a(class="nav-link" href="/account/security" aria-selected="false") Sicherheitseinstellungen
-                    a(class="nav-link" href="/account/services" aria-selected="false") Projekte und Dienste
+                    a(class="nav-link" href="/profile" aria-selected="true") Benutzerprofil
+                    a(class="nav-link" href="/security" aria-selected="false") Sicherheitseinstellungen
+                    a(class="nav-link" href="/services" aria-selected="false") Projekte und Dienste
             div(class="col-sm-9")
                 p content goes here
                 
diff --git a/views/DE/profile.pug b/views/DE/profile.pug
index 9a3fc46e..32a2aff1 100644
--- a/views/DE/profile.pug
+++ b/views/DE/profile.pug
@@ -35,8 +35,8 @@ html(lang="de")
                     span #{user.firstname} #{user.lastname}
                 div(class="nav flex-column nav-pills", id="v-pills-tab", role="tablist", aria-orientation="vertical")
                     a(class="nav-link" href="#" aria-selected="true") Benutzerprofil
-                    a(class="nav-link" href="/account/security" aria-selected="false") Sicherheitseinstellungen
-                    a(class="nav-link" href="/account/services" aria-selected="false") Projekte und Dienste
+                    a(class="nav-link" href="/security" aria-selected="false") Sicherheitseinstellungen
+                    a(class="nav-link" href="/services" aria-selected="false") Projekte und Dienste
             div(class="col-sm-9")
                 if successes
                     for success in successes
@@ -48,9 +48,23 @@ html(lang="de")
                             a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
                 form#profileForm(method="POST", action="/updateProfile")
                     div(class="form-row")
+                        div(class='form-group col-md-2')
+                            label(for="title") Anrede
+                            select#inputSalutation(name="inputSalutation", class="form-control", , value=user.salutation)
+                                option(value="") - Anrede -
+                                option(value="Herr") Herr
+                                option(value="Frau") Frau
+                                option(value="Divers") Divers
+                                script.
+                                    var salutationOptions = document.getElementById('inputSalutation').options;
+                                    for (i=0; i < salutationOptions.length; i++) {
+                                        if (salutationOptions[i].value == '#{user.salutation}')
+                                            salutationOptions[i].selected = true;
+                                    }
                         div(class='form-group col-md-2')
                             label(for="title") Titel
                             select#inputTitle(name="inputTitle", class="form-control", value=user.title)
+                                option(value="") - Titel -
                                 option(value="Prof.") Prof.
                                 option(value="Dr.") Dr.
                                 option(value="Dipl.-Ing.") Dipl.-Ing.
@@ -61,15 +75,15 @@ html(lang="de")
                                         if (titleOptions[i].value == '#{user.title}')
                                             titleOptions[i].selected = true;
                                     }
-                        div(class='form-group col-md-3')
+                        div(class='form-group col-md-2')
                             label(for="firstname") Vorname
                             input#inputFirstname(name="inputFirstname", type="text", class="form-control", placeholder="Vorname", value=user.firstname required)
-                        div(class='form-group col-md-3')
+                        div(class='form-group col-md-2')
                             label(for="lastname") Nachname
                             input#inputLastname(name="inputLastname", type="text", class="form-control", placeholder="Nachname", value=user.lastname required)
                     div(class="form-row")
                         div(class='form-group col-md-8')
-                            label(for="email") Email
+                            label(for="email") E-mail Adresse
                             input#inputEmail(name="inputEmail", type="email", class="form-control", placeholder="Email", value=email required)
                     div(class="form-row")
                         div(class='form-group col-md-8')
@@ -83,7 +97,7 @@ html(lang="de")
                         div(class='form-group col-md-8')
                             label(for="speciality") Fachgebiete
                             input#inputSpeciality(name="inputSpeciality", type="text", class="form-control", placeholder="Fachgebiete", value=user.speciality)                    
-                    input(type="submit", class="btn btn-primary", value="Update")
+                    input(type="submit", class="btn btn-primary", value="Speichern")
 
     // jQuery
     script(src="https://code.jquery.com/jquery-3.3.1.min.js")
diff --git a/views/DE/registration.pug b/views/DE/registration.pug
index f5e9973e..ab1c7e5a 100644
--- a/views/DE/registration.pug
+++ b/views/DE/registration.pug
@@ -82,7 +82,7 @@ html(lang="de")
                     p <em><small>* Pflichtfeld</small></em>
                     input#submitBtn(type="submit", class="btn btn-outline-dark btn-block", value="Senden" disabled)
                 br
-                p(class="text-center") Sie haben bereits ein Benutzerkonto? <a href="/account">Melden Sie sich hier an</a>.
+                p(class="text-center") Sie haben bereits ein Benutzerkonto? <a href="/login">Melden Sie sich hier an</a>.
                     
 
     // jQuery
diff --git a/views/DE/security.pug b/views/DE/security.pug
index 5d4a214a..560d32bc 100644
--- a/views/DE/security.pug
+++ b/views/DE/security.pug
@@ -37,9 +37,9 @@ html(lang="de")
                 h5
                     span #{user.firstName} #{user.lastName}
                 div(class="nav flex-column nav-pills", id="v-pills-tab", role="tablist", aria-orientation="vertical")
-                    a(class="nav-link" href="/account/profile" aria-selected="true") Benutzerprofil
+                    a(class="nav-link" href="/profile" aria-selected="true") Benutzerprofil
                     a(class="nav-link" href="#" aria-selected="false") Sicherheitseinstellungen
-                    a(class="nav-link" href="/account/services" aria-selected="false") Projekte und Dienste
+                    a(class="nav-link" href="/services" aria-selected="false") Projekte und Dienste
             div(class="col-sm-9")
                 if successes
                     for success in successes
@@ -53,18 +53,18 @@ html(lang="de")
                     div(class="form-group row")
                         label(for="currPwd") Aktuelles Passwort
                         input(id="inputCurrPwd", name="inputCurrPwd", type="password", class="form-control" required)
-                        div(class="invalid-feedback") Please fill in this field.
+                        div(class="invalid-feedback") Bitte füllen Sie dieses Feld aus.
                     div(class="form-group row")
                         label(for="newPwd") Neues Passwort
                         input#inputNewPwd(name="inputNewPwd", type="password", class="form-control" required)
                         span#recommendation
-                        div(class="invalid-feedback") Please fill in this field.
+                        div(class="invalid-feedback") Bitte füllen Sie dieses Feld aus.
                     div(class="form-group row")
                         label(for="confirm") Bestätigen Sie das neue Passwort
                         input#inputConfirm(name="inputConfirm", type="password", class="form-control" required)
                         span#message
-                        div(class="invalid-feedback") Please fill in this field.
-                    input#updateBtn(type="submit", class="btn btn-primary", value="Update Password" disabled)
+                        div(class="invalid-feedback") Bitte füllen Sie dieses Feld aus.
+                    input#updateBtn(type="submit", class="btn btn-primary", value="Passwort ändern" disabled)
                     
     // jQuery
     script(src="https://code.jquery.com/jquery-3.3.1.min.js")
diff --git a/views/DE/services.pug b/views/DE/services.pug
index 6ab101f3..55f5a1b6 100644
--- a/views/DE/services.pug
+++ b/views/DE/services.pug
@@ -34,8 +34,8 @@ html(lang="de")
                 h5
                     span #{user.firstName} #{user.lastName}
                 div(class="nav flex-column nav-pills", id="v-pills-tab", role="tablist", aria-orientation="vertical")
-                    a(class="nav-link" href="/account/profile" aria-selected="true") Benutzerprofil
-                    a(class="nav-link" href="/account/security" aria-selected="false") Sicherheitseinstellungen
+                    a(class="nav-link" href="/profile" aria-selected="true") Benutzerprofil
+                    a(class="nav-link" href="/security" aria-selected="false") Sicherheitseinstellungen
                     a(class="nav-link" href="#" aria-selected="false") Projekte und Dienste
             div(class="col-sm-9")
                 if successes
-- 
GitLab


From 3fecf9ff3d228f15c67aae9344dcb9b969a56321 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Wed, 4 Mar 2020 14:49:59 +0100
Subject: [PATCH 13/20] put "project-list" and "account-related-pages" on
 different folder

---
 views/DE/{ => account}/forgotPwd.pug    |  0
 views/DE/{ => account}/home.pug         |  0
 views/DE/{ => account}/profile.pug      |  0
 views/DE/{ => account}/registration.pug |  0
 views/DE/{ => account}/reset.pug        |  0
 views/DE/{ => account}/security.pug     |  0
 views/DE/{ => account}/services.pug     |  0
 views/DE/projectList/projects.pug       | 48 +++++++++++++++++++++++++
 8 files changed, 48 insertions(+)
 rename views/DE/{ => account}/forgotPwd.pug (100%)
 rename views/DE/{ => account}/home.pug (100%)
 rename views/DE/{ => account}/profile.pug (100%)
 rename views/DE/{ => account}/registration.pug (100%)
 rename views/DE/{ => account}/reset.pug (100%)
 rename views/DE/{ => account}/security.pug (100%)
 rename views/DE/{ => account}/services.pug (100%)
 create mode 100644 views/DE/projectList/projects.pug

diff --git a/views/DE/forgotPwd.pug b/views/DE/account/forgotPwd.pug
similarity index 100%
rename from views/DE/forgotPwd.pug
rename to views/DE/account/forgotPwd.pug
diff --git a/views/DE/home.pug b/views/DE/account/home.pug
similarity index 100%
rename from views/DE/home.pug
rename to views/DE/account/home.pug
diff --git a/views/DE/profile.pug b/views/DE/account/profile.pug
similarity index 100%
rename from views/DE/profile.pug
rename to views/DE/account/profile.pug
diff --git a/views/DE/registration.pug b/views/DE/account/registration.pug
similarity index 100%
rename from views/DE/registration.pug
rename to views/DE/account/registration.pug
diff --git a/views/DE/reset.pug b/views/DE/account/reset.pug
similarity index 100%
rename from views/DE/reset.pug
rename to views/DE/account/reset.pug
diff --git a/views/DE/security.pug b/views/DE/account/security.pug
similarity index 100%
rename from views/DE/security.pug
rename to views/DE/account/security.pug
diff --git a/views/DE/services.pug b/views/DE/account/services.pug
similarity index 100%
rename from views/DE/services.pug
rename to views/DE/account/services.pug
diff --git a/views/DE/projectList/projects.pug b/views/DE/projectList/projects.pug
new file mode 100644
index 00000000..49b656ea
--- /dev/null
+++ b/views/DE/projectList/projects.pug
@@ -0,0 +1,48 @@
+doctype html
+html(lang="de")
+  head
+    title= "Project List"
+    meta(charset="UTF-8")
+    meta(name="viewport", content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no")
+    link(rel="stylesheet", type="text/css", href="https://transfer.hft-stuttgart.de/css/bootstrap/bootstrap.css")
+    link(rel="stylesheet", href="https://use.fontawesome.com/releases/v5.8.2/css/all.css", integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay", crossorigin="anonymous")
+    style.
+        .collapse {
+            display: none;
+        }
+        .collapse.in {
+            display: block;
+        }
+        .collapsing {
+            position: relative;
+            height: 0;
+            overflow: hidden;
+            -webkit-transition-timing-function: ease;
+            -o-transition-timing-function: ease;
+            transition-timing-function: ease;
+            -webkit-transition-duration: .35s;
+            -o-transition-duration: .35s;
+            transition-duration: .35s;
+            -webkit-transition-property: height,visibility;
+            -o-transition-property: height,visibility;
+            transition-property: height,visibility;
+        }
+        .warning {
+            color: red;
+            font-size: 11px;
+        }
+  body
+    div(class="container-fluid")
+        div(class="row")
+            div(class="col-md-6 offset-md-2")
+                h3(class="mb-3 font-weight-bold") Hello World
+            div(class="col-md-6 offset-md-3")
+                p Content: Project List in a table
+                    
+
+    // jQuery
+    script(src="https://code.jquery.com/jquery-3.3.1.min.js")
+    script(src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js", integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1", crossorigin="anonymous")
+    // Bootstrap
+    script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous")
+    script(src="https://transfer.hft-stuttgart.de/js/headfoot.js")
\ No newline at end of file
-- 
GitLab


From a6fa8da93a13a1b895751c72aea5b310cf35b505 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Wed, 4 Mar 2020 14:50:32 +0100
Subject: [PATCH 14/20] add route for project-list

---
 routes/routes.js | 33 ++++++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 9 deletions(-)

diff --git a/routes/routes.js b/routes/routes.js
index 09d5fe6b..481e2fb9 100644
--- a/routes/routes.js
+++ b/routes/routes.js
@@ -114,12 +114,12 @@ module.exports = function (app, config, passport, i18n) {
   
   var lang = 'DE'
 
-  // ======== APP ROUTES ====================
+  // ======== APP ROUTES - ACCOUNT ====================
   app.get('/', function (req, res) {
     if (req.isAuthenticated()) {
       methods.getUserByEmail(req.user.email, function(data, err){
         if (!err) {
-          res.render(lang+'/home', {
+          res.render(lang+'/account/home', {
             user: data
           });
         }
@@ -167,7 +167,7 @@ module.exports = function (app, config, passport, i18n) {
     if (req.isAuthenticated()) {
       methods.getUserByEmail(req.user.email, function(data, err){
         if (!err) {
-          res.render(lang+'/profile', {
+          res.render(lang+'/account/profile', {
             user: data,
             email: req.user.email
           });
@@ -231,7 +231,7 @@ module.exports = function (app, config, passport, i18n) {
           }
 
           // render the page
-          res.render(lang+'/services', {
+          res.render(lang+'/account/services', {
             user: req.user,
             project: allProjects
           });
@@ -244,7 +244,7 @@ module.exports = function (app, config, passport, i18n) {
 
   app.get('/security', function (req, res) {
     if (req.isAuthenticated()) {
-      res.render(lang+'/security', {
+      res.render(lang+'/account/security', {
         user: req.user // useful for view engine, useless for HTML
       });
     } else {
@@ -362,7 +362,7 @@ module.exports = function (app, config, passport, i18n) {
   });
 
   app.get('/forgotPwd', function (req, res) {
-    res.render(lang+'/forgotPwd', {
+    res.render(lang+'/account/forgotPwd', {
       user: req.user
     });
   });
@@ -446,7 +446,7 @@ module.exports = function (app, config, passport, i18n) {
         res.redirect('/forgotPwd'); // localhost
       }
       else {
-        res.render(lang+'/reset');
+        res.render(lang+'/account/reset');
       }
     });
   });
@@ -498,7 +498,7 @@ module.exports = function (app, config, passport, i18n) {
 
   // todo: user registration with captcha
   app.get('/registration', function(req, res) {
-    res.render(lang+'/registration')
+    res.render(lang+'/account/registration')
   })
 
   app.post('/registration', function(req, res) {
@@ -543,7 +543,6 @@ module.exports = function (app, config, passport, i18n) {
     });
   })
 
-  
   app.get('/email/:email', function(req, res) {
     methods.checkUserEmail(req.params.email, function(err, user){
       if (!err) {
@@ -557,4 +556,20 @@ module.exports = function (app, config, passport, i18n) {
     })
   })
 
+  // ======== APP ROUTES - PROJECT LIST ====================
+  app.get('/project', function (req, res) {
+    if (req.isAuthenticated()) {
+      console.log("true")
+      res.render(lang+'/projectList/projects', {
+        isUserAuthenticated: true
+      });
+    }
+    else {
+      console.log("false")
+      res.render(lang+'/projectList/projects', {
+        isUserAuthenticated: false
+      });
+    }
+  })
+
 };
-- 
GitLab


From 7df3b7a0063fd9dbc81a3593ce3c86207f7fb334 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Wed, 4 Mar 2020 15:06:20 +0100
Subject: [PATCH 15/20] add if-else condition for project-list header

---
 routes/routes.js                  | 2 --
 views/DE/projectList/projects.pug | 7 +++++--
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/routes/routes.js b/routes/routes.js
index 481e2fb9..1632240d 100644
--- a/routes/routes.js
+++ b/routes/routes.js
@@ -559,13 +559,11 @@ module.exports = function (app, config, passport, i18n) {
   // ======== APP ROUTES - PROJECT LIST ====================
   app.get('/project', function (req, res) {
     if (req.isAuthenticated()) {
-      console.log("true")
       res.render(lang+'/projectList/projects', {
         isUserAuthenticated: true
       });
     }
     else {
-      console.log("false")
       res.render(lang+'/projectList/projects', {
         isUserAuthenticated: false
       });
diff --git a/views/DE/projectList/projects.pug b/views/DE/projectList/projects.pug
index 49b656ea..5b1a10a5 100644
--- a/views/DE/projectList/projects.pug
+++ b/views/DE/projectList/projects.pug
@@ -38,11 +38,14 @@ html(lang="de")
                 h3(class="mb-3 font-weight-bold") Hello World
             div(class="col-md-6 offset-md-3")
                 p Content: Project List in a table
-                    
 
     // jQuery
     script(src="https://code.jquery.com/jquery-3.3.1.min.js")
     script(src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js", integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1", crossorigin="anonymous")
     // Bootstrap
     script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous")
-    script(src="https://transfer.hft-stuttgart.de/js/headfoot.js")
\ No newline at end of file
+    // Header
+    if isUserAuthenticated
+        script(src="/js/headfootLogout.js")
+    else
+        script(src="https://transfer.hft-stuttgart.de/js/headfoot.js")
\ No newline at end of file
-- 
GitLab


From d625f1f8167cf7544b87947eec35472d2ea33ad6 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Wed, 4 Mar 2020 17:45:35 +0100
Subject: [PATCH 16/20] show project list in a table

---
 routes/routes.js                  | 84 +++++++++++++++++++++++++++----
 views/DE/projectList/projects.pug | 56 +++++++++++++++++++--
 2 files changed, 125 insertions(+), 15 deletions(-)

diff --git a/routes/routes.js b/routes/routes.js
index 1632240d..dc24fce6 100644
--- a/routes/routes.js
+++ b/routes/routes.js
@@ -558,16 +558,80 @@ module.exports = function (app, config, passport, i18n) {
 
   // ======== APP ROUTES - PROJECT LIST ====================
   app.get('/project', function (req, res) {
-    if (req.isAuthenticated()) {
-      res.render(lang+'/projectList/projects', {
-        isUserAuthenticated: true
-      });
-    }
-    else {
-      res.render(lang+'/projectList/projects', {
-        isUserAuthenticated: false
-      });
-    }
+    async.waterfall([
+      // get all projects from projectdb
+      function(done) {
+        methods.getAllProjects(function(projectsOverview, err) {
+          if (!err) {
+            done(err, projectsOverview)
+          }
+        })
+      },
+      // create JSON object of projects and user status for front-end
+      function(projectsOverview, done) {
+      //  var allProjects = []
+        var activeProjects = []
+        var nonActiveProjects = []
+/*
+        for (var i = 0; i < projectsOverview.length; i++) {
+          allProjects.push({
+            id: projectsOverview[i].id,
+            status: projectsOverview[i].projectstatus,
+            logo: projectsOverview[i].logo,
+            akronym: projectsOverview[i].pname,
+            title: projectsOverview[i].title,
+            summary: projectsOverview[i].onelinesummary,
+            category: projectsOverview[i].category,
+            cp: projectsOverview[i].contact_email
+          })
+        }
+*/
+        for (var i = 0; i < projectsOverview.length; i++) {
+          if (projectsOverview[i].projectstatus == 0) {
+            nonActiveProjects.push({
+              id: projectsOverview[i].id,
+              logo: projectsOverview[i].logo,
+              akronym: projectsOverview[i].pname,
+              title: projectsOverview[i].title,
+              summary: projectsOverview[i].onelinesummary,
+              category: projectsOverview[i].category,
+              cp: projectsOverview[i].contact_email
+            })
+          }
+          else if (projectsOverview[i].projectstatus == 1) {
+            activeProjects.push({
+              id: projectsOverview[i].id,
+              logo: projectsOverview[i].logo,
+              akronym: projectsOverview[i].pname,
+              title: projectsOverview[i].title,
+              summary: projectsOverview[i].onelinesummary,
+              category: projectsOverview[i].category,
+              cp: projectsOverview[i].contact_email
+            })
+          }
+        }
+
+        // render the page
+        if (req.isAuthenticated()) {
+          res.render(lang+'/projectList/projects', {
+            isUserAuthenticated: true,
+            //project: allProjects
+            nonActive: nonActiveProjects,
+            active: activeProjects
+          });
+        }
+        else {
+          res.render(lang+'/projectList/projects', {
+            isUserAuthenticated: false,
+            //project: allProjects
+            nonActive: nonActiveProjects,
+            active: activeProjects
+          });
+        }
+      }
+    ])
+
+    
   })
 
 };
diff --git a/views/DE/projectList/projects.pug b/views/DE/projectList/projects.pug
index 5b1a10a5..490ce91b 100644
--- a/views/DE/projectList/projects.pug
+++ b/views/DE/projectList/projects.pug
@@ -33,11 +33,57 @@ html(lang="de")
         }
   body
     div(class="container-fluid")
-        div(class="row")
-            div(class="col-md-6 offset-md-2")
-                h3(class="mb-3 font-weight-bold") Hello World
-            div(class="col-md-6 offset-md-3")
-                p Content: Project List in a table
+        h3(class="mb-3 font-weight-bold") Aktive Projekte
+        table(class="table table-striped")
+            thead
+                tr
+                    th Logo
+                    th Akronym
+                    th Title
+                    th Kernziel
+                    th Kategorie
+                    th Ansprechpartner
+                    th Projektinhalte
+            tbody
+                for item in active
+                    tr
+                        //td #{item.status}
+                        td
+                            img(src=item.logo, width="40", height="40")
+                        td #{item.akronym}
+                        td #{item.title}
+                        td #{item.summary}
+                        td #{item.category}
+                        td
+                            a(class="nav-link", href="mailto:"+ item.cp) #{item.cp}
+                        td
+                            a(class="nav-link", href="https://m4lab.hft-stuttgart.de/projectoverview?projectID="+ item.id) Zur Projektübersicht
+        br
+        h3(class="mb-3 font-weight-bold") Abgeschlossene Projekte
+        table(class="table table-striped")
+            thead
+                tr
+                    th Logo
+                    th Akronym
+                    th Title
+                    th Kernziel
+                    th Kategorie
+                    th Ansprechpartner
+                    th Projektinhalte
+            tbody
+                for item in nonActive
+                    tr
+                        //td #{item.status}
+                        td
+                            img(src=item.logo, width="40", height="40")
+                        td #{item.akronym}
+                        td #{item.title}
+                        td #{item.summary}
+                        td #{item.category}
+                        td
+                            a(class="nav-link", href="mailto:"+ item.cp) #{item.cp}
+                        td
+                            a(class="nav-link", href="https://m4lab.hft-stuttgart.de/projectoverview?projectID="+ item.id) Zur Projektübersicht 
 
     // jQuery
     script(src="https://code.jquery.com/jquery-3.3.1.min.js")
-- 
GitLab


From 4dc1bc6097cfe249424e12bf8be97d25a60a2bc8 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Thu, 5 Mar 2020 09:51:36 +0100
Subject: [PATCH 17/20] add gitlab link to project list table

---
 routes/routes.js                              | 48 +++++--------------
 .../DE/{projectList => project}/projects.pug  | 18 ++++++-
 2 files changed, 28 insertions(+), 38 deletions(-)
 rename views/DE/{projectList => project}/projects.pug (75%)

diff --git a/routes/routes.js b/routes/routes.js
index dc24fce6..930bf3b4 100644
--- a/routes/routes.js
+++ b/routes/routes.js
@@ -556,7 +556,7 @@ module.exports = function (app, config, passport, i18n) {
     })
   })
 
-  // ======== APP ROUTES - PROJECT LIST ====================
+  // ======== APP ROUTES - PROJECT ====================
   app.get('/project', function (req, res) {
     async.waterfall([
       // get all projects from projectdb
@@ -567,71 +567,47 @@ module.exports = function (app, config, passport, i18n) {
           }
         })
       },
-      // create JSON object of projects and user status for front-end
+      // create JSON object for front-end
       function(projectsOverview, done) {
-      //  var allProjects = []
         var activeProjects = []
         var nonActiveProjects = []
-/*
+
         for (var i = 0; i < projectsOverview.length; i++) {
-          allProjects.push({
+          var project = {
             id: projectsOverview[i].id,
-            status: projectsOverview[i].projectstatus,
             logo: projectsOverview[i].logo,
             akronym: projectsOverview[i].pname,
             title: projectsOverview[i].title,
             summary: projectsOverview[i].onelinesummary,
             category: projectsOverview[i].category,
-            cp: projectsOverview[i].contact_email
-          })
-        }
-*/
-        for (var i = 0; i < projectsOverview.length; i++) {
+            cp: projectsOverview[i].contact_email,
+            gitlab: projectsOverview[i].gitlab
+          }
           if (projectsOverview[i].projectstatus == 0) {
-            nonActiveProjects.push({
-              id: projectsOverview[i].id,
-              logo: projectsOverview[i].logo,
-              akronym: projectsOverview[i].pname,
-              title: projectsOverview[i].title,
-              summary: projectsOverview[i].onelinesummary,
-              category: projectsOverview[i].category,
-              cp: projectsOverview[i].contact_email
-            })
+            nonActiveProjects.push(project)
           }
           else if (projectsOverview[i].projectstatus == 1) {
-            activeProjects.push({
-              id: projectsOverview[i].id,
-              logo: projectsOverview[i].logo,
-              akronym: projectsOverview[i].pname,
-              title: projectsOverview[i].title,
-              summary: projectsOverview[i].onelinesummary,
-              category: projectsOverview[i].category,
-              cp: projectsOverview[i].contact_email
-            })
+            activeProjects.push(project)
           }
         }
 
         // render the page
         if (req.isAuthenticated()) {
-          res.render(lang+'/projectList/projects', {
+          res.render(lang+'/project/projects', {
             isUserAuthenticated: true,
-            //project: allProjects
             nonActive: nonActiveProjects,
             active: activeProjects
           });
         }
         else {
-          res.render(lang+'/projectList/projects', {
+          res.render(lang+'/project/projects', {
             isUserAuthenticated: false,
-            //project: allProjects
             nonActive: nonActiveProjects,
             active: activeProjects
           });
         }
       }
     ])
-
-    
   })
 
-};
+};
\ No newline at end of file
diff --git a/views/DE/projectList/projects.pug b/views/DE/project/projects.pug
similarity index 75%
rename from views/DE/projectList/projects.pug
rename to views/DE/project/projects.pug
index 490ce91b..35cd2c92 100644
--- a/views/DE/projectList/projects.pug
+++ b/views/DE/project/projects.pug
@@ -33,6 +33,7 @@ html(lang="de")
         }
   body
     div(class="container-fluid")
+        // Active projects
         h3(class="mb-3 font-weight-bold") Aktive Projekte
         table(class="table table-striped")
             thead
@@ -57,8 +58,15 @@ html(lang="de")
                         td
                             a(class="nav-link", href="mailto:"+ item.cp) #{item.cp}
                         td
-                            a(class="nav-link", href="https://m4lab.hft-stuttgart.de/projectoverview?projectID="+ item.id) Zur Projektübersicht
+                            a(class="nav-link", href="https://m4lab.hft-stuttgart.de/projectoverview?projectID="+item.id) Zur Projektübersicht
+                            if item.gitlab
+                                a(class="nav-link", href="https://transfer.hft-stuttgart.de/gitlab/"+item.gitlab+"/tree/master") Projektdateien
+                                a(class="nav-link", href="https://transfer.hft-stuttgart.de/gitlab/"+item.gitlab+"/wikis/home") Projektwiki
+                            else
+                                a(class="nav-link", href="#") Projektdateien
+                                a(class="nav-link", href="#") Projektwiki
         br
+        // Non-active projects
         h3(class="mb-3 font-weight-bold") Abgeschlossene Projekte
         table(class="table table-striped")
             thead
@@ -83,7 +91,13 @@ html(lang="de")
                         td
                             a(class="nav-link", href="mailto:"+ item.cp) #{item.cp}
                         td
-                            a(class="nav-link", href="https://m4lab.hft-stuttgart.de/projectoverview?projectID="+ item.id) Zur Projektübersicht 
+                            a(class="nav-link", href="https://m4lab.hft-stuttgart.de/projectoverview?projectID="+item.id) Zur Projektübersicht
+                            if item.gitlab
+                                a(class="nav-link", href="https://transfer.hft-stuttgart.de/gitlab/"+item.gitlab+"/tree/master") Projektdateien
+                                a(class="nav-link", href="https://transfer.hft-stuttgart.de/gitlab/"+item.gitlab+"/wikis/home") Projektwiki
+                            else
+                                a(class="nav-link", href="#") Projektdateien
+                                a(class="nav-link", href="#") Projektwiki
 
     // jQuery
     script(src="https://code.jquery.com/jquery-3.3.1.min.js")
-- 
GitLab


From 2786292c50e2f822e5c08ca9f9af9d5523be2ea6 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Thu, 5 Mar 2020 13:09:10 +0100
Subject: [PATCH 18/20] add project overview: form and skeleton

---
 routes/routes.js                        |  14 +++
 views/DE/project/addProjectOverview.pug | 113 ++++++++++++++++++++++++
 views/DE/project/projects.pug           |  18 ++--
 3 files changed, 137 insertions(+), 8 deletions(-)
 create mode 100644 views/DE/project/addProjectOverview.pug

diff --git a/routes/routes.js b/routes/routes.js
index 930bf3b4..abd4f03f 100644
--- a/routes/routes.js
+++ b/routes/routes.js
@@ -610,4 +610,18 @@ module.exports = function (app, config, passport, i18n) {
     ])
   })
 
+  app.get('/addprojectoverview', function (req, res) {
+    //res.render(lang+'/project/addProjectOverview')
+    if (req.isAuthenticated()) {
+      res.render(lang+'/project/addProjectOverview')
+    }
+    else {
+      res.redirect('/login')
+    } 
+  })
+  
+  app.post('/addprojectoverview', function (req, res) {
+    console.log(req.body)
+  })
+
 };
\ No newline at end of file
diff --git a/views/DE/project/addProjectOverview.pug b/views/DE/project/addProjectOverview.pug
new file mode 100644
index 00000000..a6499a87
--- /dev/null
+++ b/views/DE/project/addProjectOverview.pug
@@ -0,0 +1,113 @@
+doctype html
+html(lang="de")
+  head
+    title= "Add Project Overview"
+    meta(charset="UTF-8")
+    meta(name="viewport", content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no")
+    link(rel="stylesheet", type="text/css", href="https://transfer.hft-stuttgart.de/css/bootstrap/bootstrap.css")
+    link(rel="stylesheet", href="https://use.fontawesome.com/releases/v5.8.2/css/all.css", integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay", crossorigin="anonymous")
+    style.
+        .collapse {
+            display: none;
+        }
+        .collapse.in {
+            display: block;
+        }
+        .collapsing {
+            position: relative;
+            height: 0;
+            overflow: hidden;
+            -webkit-transition-timing-function: ease;
+            -o-transition-timing-function: ease;
+            transition-timing-function: ease;
+            -webkit-transition-duration: .35s;
+            -o-transition-duration: .35s;
+            transition-duration: .35s;
+            -webkit-transition-property: height,visibility;
+            -o-transition-property: height,visibility;
+            transition-property: height,visibility;
+        }
+        .warning {
+            color: red;
+            font-size: 11px;
+        }
+  body
+    div(class="container-fluid")
+        div(class="row")
+            div(class="col-md-6 offset-md-2")
+                h4(class="mb-3 font-weight-bold") Neues Projekt
+            div(class="col-md-6 offset-md-3")
+                if successes
+                    for success in successes
+                        div.alert.alert-success.alert-dismissible #{ success }
+                            a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
+                if errors
+                    for error, i in errors
+                        div.alert.alert-danger.alert-dismissible.fade.show #{ error }
+                            a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
+                form(method="POST")
+                    div(class='form-row')
+                        div(class='form-group col-md-12')
+                            input#inputPname(name="pname" class="form-control" type="text" placeholder="human-readable short project name*" required)
+                        div(class="form-group col-md-12")
+                            input#inputTitle(name="title" class="form-control" type="text" placeholder="official title of the project*" required)
+                        div(class="form-group col-md-12")
+                            input#inputSummary(name="summary" class="form-control" type="text" placeholder="one line summery of the project")
+                        div(class="form-group col-md-12")
+                            input#inputCategory(name="category" class="form-control" type="text" placeholder="category of the project")
+                        //div(class="form-group col-md-12")
+                            input#inputLogo(name="logo" class="form-control" type="text" placeholder="official logo of the project")
+                        //div(class="form-group col-md-12")
+                            input#inputWiki(name="wiki" class="form-control" type="text") 
+                    h5(class="mb-3 font-weight-bold") Content
+                    div(class='form-row')
+                        div(class='form-group col-md-12')
+                            textarea#inputOverview(name="overview" class="form-control" type="text" rows="5" placeholder="overview")
+                        div(class="form-group col-md-12")
+                            textarea#inputQuestion(name="question" class="form-control" type="text" rows="5" placeholder="question")
+                        div(class='form-group col-md-12')
+                            textarea#inputApproach(name="approach" class="form-control" type="text" rows="5" placeholder="approach")
+                        div(class="form-group col-md-12")
+                            textarea#inputResult(name="result" class="form-control" type="text" rows="5" placeholder="result")
+                        div(class="form-group col-md-12")
+                            input#inputKeywords(name="keywords" class="form-control" type="text" placeholder="keywords")
+                    h5(class="mb-3 font-weight-bold") Info
+                    div(class='form-row')
+                        div(class='form-group col-md-12')
+                            textarea#inputAnnouncement(name="announcement" class="form-control" type="text" rows="5" placeholder="Ausschreibung")
+                        div(class="form-group col-md-12")
+                            input#inputTerm(name="term" class="form-control" type="text" placeholder="Laufzeit")
+                        div(class='form-group col-md-12')
+                            textarea#inputFurtherDetails(name="furtherDetails" class="form-control" type="text" rows="5" placeholder="Mehr informationen")
+                        div(class="form-group col-md-12")
+                            input#inputWebsite(name="website" class="form-control" type="text" placeholder="website")
+                    h5(class="mb-3 font-weight-bold") Images
+                    div(class='form-row')
+                        div(class="form-group col-md-12")
+                            input#inputSrc(name="src" class="form-control" type="text" placeholder="link to the image source")
+                        div(class="form-group col-md-12")
+                            input#inputCaption(name="caption" class="form-control" type="text" placeholder="caption of the image")
+                    h5(class="mb-3 font-weight-bold") Contact
+                    div(class='form-row')
+                        div(class="form-group col-md-4")
+                            input#inputContactFirstname(name="contactFirstname" class="form-control" type="text" placeholder="contact firstname")
+                        div(class="form-group col-md-4")
+                            input#inputContactLastname(name="contactLastname" class="form-control" type="text" placeholder="contact lastname")
+                        div(class="form-group col-md-4")
+                            input#inputContactEmail(name="contactEmail" class="form-control" type="text" placeholder="contact email")
+                        div(class="form-group col-md-4")
+                            input#inputLeaderFirstname(name="leaderFirstname" class="form-control" type="text" placeholder="leader firstname")
+                        div(class="form-group col-md-4")
+                            input#inputLeaderLastname(name="leaderLastname" class="form-control" type="text" placeholder="leader lastname")
+                        div(class="form-group col-md-4")
+                            input#inputLeaderEmail(name="leaderEmail" class="form-control" type="text" placeholder="leader email")
+                    p <em><small>* Pflichtfeld</small></em>
+                    input#submitBtn(type="submit", class="btn btn-outline-dark btn-block", value="Projekt Anlegen")
+
+    // jQuery
+    script(src="https://code.jquery.com/jquery-3.3.1.min.js")
+    script(src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js", integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1", crossorigin="anonymous")
+    // Bootstrap
+    script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous")
+    // Header
+    script(src="/js/headfootLogout.js")
\ No newline at end of file
diff --git a/views/DE/project/projects.pug b/views/DE/project/projects.pug
index 35cd2c92..a59cdf45 100644
--- a/views/DE/project/projects.pug
+++ b/views/DE/project/projects.pug
@@ -33,6 +33,12 @@ html(lang="de")
         }
   body
     div(class="container-fluid")
+        if isUserAuthenticated
+            p Auf dieser Seite sehen Sie die Liste der über dieses Portal veröffentlichten Projekte.
+            a(href="/addprojectoverview" class="btn btn-primary" role="button" aria-pressed="true") Projekt anlegen
+        else
+            p Auf dieser Seite sehen Sie die Liste der über dieses Portal veröffentlichten Projekte.
+            p Möchten Sie ein neues Projekt anlegen, dann klicken Sie bitte auf #[a(href="/addprojectoverview") Anmelden und Projekt anlegen]
         // Active projects
         h3(class="mb-3 font-weight-bold") Aktive Projekte
         table(class="table table-striped")
@@ -55,10 +61,8 @@ html(lang="de")
                         td #{item.title}
                         td #{item.summary}
                         td #{item.category}
-                        td
-                            a(class="nav-link", href="mailto:"+ item.cp) #{item.cp}
-                        td
-                            a(class="nav-link", href="https://m4lab.hft-stuttgart.de/projectoverview?projectID="+item.id) Zur Projektübersicht
+                        td #[a(class="nav-link", href="mailto:"+ item.cp) #{item.cp}]
+                        td #[a(class="nav-link", href="https://m4lab.hft-stuttgart.de/projectoverview?projectID="+item.id) Zur Projektübersicht]
                             if item.gitlab
                                 a(class="nav-link", href="https://transfer.hft-stuttgart.de/gitlab/"+item.gitlab+"/tree/master") Projektdateien
                                 a(class="nav-link", href="https://transfer.hft-stuttgart.de/gitlab/"+item.gitlab+"/wikis/home") Projektwiki
@@ -88,10 +92,8 @@ html(lang="de")
                         td #{item.title}
                         td #{item.summary}
                         td #{item.category}
-                        td
-                            a(class="nav-link", href="mailto:"+ item.cp) #{item.cp}
-                        td
-                            a(class="nav-link", href="https://m4lab.hft-stuttgart.de/projectoverview?projectID="+item.id) Zur Projektübersicht
+                        td #[a(class="nav-link", href="mailto:"+ item.cp) #{item.cp}]
+                        td #[a(class="nav-link", href="https://m4lab.hft-stuttgart.de/projectoverview?projectID="+item.id) Zur Projektübersicht]
                             if item.gitlab
                                 a(class="nav-link", href="https://transfer.hft-stuttgart.de/gitlab/"+item.gitlab+"/tree/master") Projektdateien
                                 a(class="nav-link", href="https://transfer.hft-stuttgart.de/gitlab/"+item.gitlab+"/wikis/home") Projektwiki
-- 
GitLab


From f88e6c8a625c6533fe616ffd20f03d6c327576d9 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Thu, 5 Mar 2020 15:36:59 +0100
Subject: [PATCH 19/20] add project overview: insert data to db

---
 routes/methods.js                       |  6 +++
 routes/routes.js                        | 50 +++++++++++++++++++++++--
 views/DE/project/addProjectOverview.pug | 22 ++++++-----
 views/DE/project/projects.pug           |  4 ++
 4 files changed, 68 insertions(+), 14 deletions(-)

diff --git a/routes/methods.js b/routes/methods.js
index 5a7dc652..3ffec719 100644
--- a/routes/methods.js
+++ b/routes/methods.js
@@ -138,6 +138,12 @@ var methods = {
             if (err) throw err;
             callback(rows[0], err);
         })
+    },
+    addProjectOverview: function(data, callback) {
+        dbconn.project.query('INSERT INTO project_overview SET ?', data, function (err, rows, fields){
+            if (err) throw err;
+            callback(err);
+        })
     }
 };
 
diff --git a/routes/routes.js b/routes/routes.js
index abd4f03f..4a757553 100644
--- a/routes/routes.js
+++ b/routes/routes.js
@@ -611,17 +611,59 @@ module.exports = function (app, config, passport, i18n) {
   })
 
   app.get('/addprojectoverview', function (req, res) {
-    //res.render(lang+'/project/addProjectOverview')
     if (req.isAuthenticated()) {
       res.render(lang+'/project/addProjectOverview')
     }
     else {
       res.redirect('/login')
-    } 
+    }
   })
   
   app.post('/addprojectoverview', function (req, res) {
-    console.log(req.body)
+    if (req.isAuthenticated()) {
+      var wiki = 0
+      if (req.body.wiki)
+        wiki = 1
+
+      var projectOverviewData = {
+        pname: req.body.pname,
+        title: req.body.title,
+        onelinesummary: req.body.summary,
+        category: req.body.category,
+        logo: req.body.logo,
+        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: req.body.term,
+        further_details: req.body.furtherDetails,
+        website: req.body.website,
+        src: req.body.src,
+        caption: req.body.caption,
+        contact_firstname: req.body.contactFirstname,
+        contact_lastname: req.body.contactLastname,
+        contact_email: req.body.contactEmail,
+        leader_firstname: req.body.leaderFirstname,
+        leader_lastname: req.body.leaderLastname,
+        leader_email: req.body.leaderEmail
+      }
+      
+      methods.addProjectOverview(projectOverviewData, function(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');
+        }
+      })
+    }
   })
-
+  
 };
\ No newline at end of file
diff --git a/views/DE/project/addProjectOverview.pug b/views/DE/project/addProjectOverview.pug
index a6499a87..7b40b54f 100644
--- a/views/DE/project/addProjectOverview.pug
+++ b/views/DE/project/addProjectOverview.pug
@@ -37,10 +37,6 @@ html(lang="de")
             div(class="col-md-6 offset-md-2")
                 h4(class="mb-3 font-weight-bold") Neues Projekt
             div(class="col-md-6 offset-md-3")
-                if successes
-                    for success in successes
-                        div.alert.alert-success.alert-dismissible #{ success }
-                            a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
                 if errors
                     for error, i in errors
                         div.alert.alert-danger.alert-dismissible.fade.show #{ error }
@@ -52,13 +48,19 @@ html(lang="de")
                         div(class="form-group col-md-12")
                             input#inputTitle(name="title" class="form-control" type="text" placeholder="official title of the project*" required)
                         div(class="form-group col-md-12")
-                            input#inputSummary(name="summary" class="form-control" type="text" placeholder="one line summery of the project")
+                            input#inputSummary(name="summary" class="form-control" type="text" placeholder="one line summary of the project")
                         div(class="form-group col-md-12")
                             input#inputCategory(name="category" class="form-control" type="text" placeholder="category of the project")
-                        //div(class="form-group col-md-12")
+                        div(class="form-group col-md-12")
                             input#inputLogo(name="logo" class="form-control" type="text" placeholder="official logo of the project")
-                        //div(class="form-group col-md-12")
-                            input#inputWiki(name="wiki" class="form-control" type="text") 
+                        div(class="form-group col-md-12")
+                            div(class="input-group mb-3")
+                                input#inputGitlabURL(name="gitlabURL" type="text" class="form-control" placeholder="M4_LAB GitLab Project URL, z.B. https://transfer.hft-stuttgart.de/gitlab/username/projectname")
+                                div(class="input-group-prepend")
+                                    div(class="input-group-text")
+                                        input#inputWiki(name="wiki" type="checkbox")
+                                        | &nbsp; Wiki
+                                
                     h5(class="mb-3 font-weight-bold") Content
                     div(class='form-row')
                         div(class='form-group col-md-12')
@@ -94,13 +96,13 @@ html(lang="de")
                         div(class="form-group col-md-4")
                             input#inputContactLastname(name="contactLastname" class="form-control" type="text" placeholder="contact lastname")
                         div(class="form-group col-md-4")
-                            input#inputContactEmail(name="contactEmail" class="form-control" type="text" placeholder="contact email")
+                            input#inputContactEmail(name="contactEmail" class="form-control" type="email" placeholder="contact email")
                         div(class="form-group col-md-4")
                             input#inputLeaderFirstname(name="leaderFirstname" class="form-control" type="text" placeholder="leader firstname")
                         div(class="form-group col-md-4")
                             input#inputLeaderLastname(name="leaderLastname" class="form-control" type="text" placeholder="leader lastname")
                         div(class="form-group col-md-4")
-                            input#inputLeaderEmail(name="leaderEmail" class="form-control" type="text" placeholder="leader email")
+                            input#inputLeaderEmail(name="leaderEmail" class="form-control" type="email" placeholder="leader email")
                     p <em><small>* Pflichtfeld</small></em>
                     input#submitBtn(type="submit", class="btn btn-outline-dark btn-block", value="Projekt Anlegen")
 
diff --git a/views/DE/project/projects.pug b/views/DE/project/projects.pug
index a59cdf45..10987e62 100644
--- a/views/DE/project/projects.pug
+++ b/views/DE/project/projects.pug
@@ -39,6 +39,10 @@ html(lang="de")
         else
             p Auf dieser Seite sehen Sie die Liste der über dieses Portal veröffentlichten Projekte.
             p Möchten Sie ein neues Projekt anlegen, dann klicken Sie bitte auf #[a(href="/addprojectoverview") Anmelden und Projekt anlegen]
+        if successes
+            for success in successes
+                div.alert.alert-success.alert-dismissible #{ success }
+                    a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
         // Active projects
         h3(class="mb-3 font-weight-bold") Aktive Projekte
         table(class="table table-striped")
-- 
GitLab


From 423eb5c0e9d69705f15ebf6b25882fd6fabff322 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Thu, 5 Mar 2020 15:44:26 +0100
Subject: [PATCH 20/20] update gitlab link

---
 views/DE/project/projects.pug | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/views/DE/project/projects.pug b/views/DE/project/projects.pug
index 10987e62..56f65c10 100644
--- a/views/DE/project/projects.pug
+++ b/views/DE/project/projects.pug
@@ -68,8 +68,8 @@ html(lang="de")
                         td #[a(class="nav-link", href="mailto:"+ item.cp) #{item.cp}]
                         td #[a(class="nav-link", href="https://m4lab.hft-stuttgart.de/projectoverview?projectID="+item.id) Zur Projektübersicht]
                             if item.gitlab
-                                a(class="nav-link", href="https://transfer.hft-stuttgart.de/gitlab/"+item.gitlab+"/tree/master") Projektdateien
-                                a(class="nav-link", href="https://transfer.hft-stuttgart.de/gitlab/"+item.gitlab+"/wikis/home") Projektwiki
+                                a(class="nav-link", href=item.gitlab+"/tree/master") Projektdateien
+                                a(class="nav-link", href=item.gitlab+"/wikis/home") Projektwiki
                             else
                                 a(class="nav-link", href="#") Projektdateien
                                 a(class="nav-link", href="#") Projektwiki
-- 
GitLab