From 2d02cbe9b25127bfffeb77460faec5c21f74697c Mon Sep 17 00:00:00 2001
From: Wolfgang Knopki <wolfgang.knopki@hft-stuttgart.de>
Date: Mon, 9 Nov 2020 14:19:48 +0100
Subject: [PATCH 01/13] removed hardcoded js paths

---
 views/DE/project/addProjectOverview.pug    | 2 +-
 views/DE/project/manageProjectOverview.pug | 2 +-
 views/DE/project/projects.pug              | 2 +-
 views/EN/project/mailinglists.pug          | 2 +-
 views/EN/project/projects.pug              | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/views/DE/project/addProjectOverview.pug b/views/DE/project/addProjectOverview.pug
index 44a17b6..1e53814 100644
--- a/views/DE/project/addProjectOverview.pug
+++ b/views/DE/project/addProjectOverview.pug
@@ -115,7 +115,7 @@ html(lang="de")
     // 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="https://transfer.hft-stuttgart.de/js/headfoot.js")
+    script(src="/js/headfoot.js")
     script.
         $( function() {
             $.datepicker.setDefaults( $.datepicker.regional["de"] );
diff --git a/views/DE/project/manageProjectOverview.pug b/views/DE/project/manageProjectOverview.pug
index 1219324..9d4e4c7 100644
--- a/views/DE/project/manageProjectOverview.pug
+++ b/views/DE/project/manageProjectOverview.pug
@@ -115,7 +115,7 @@ html(lang="de")
     // 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="https://transfer.hft-stuttgart.de/js/headfootLogout.js")
+    script(src="/js/headfootLogout.js")
     script.
         $( function() {
             $.datepicker.setDefaults( $.datepicker.regional["de"] );
diff --git a/views/DE/project/projects.pug b/views/DE/project/projects.pug
index 55682c0..1462f93 100644
--- a/views/DE/project/projects.pug
+++ b/views/DE/project/projects.pug
@@ -88,4 +88,4 @@ html(lang="de")
     // 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="https://transfer.hft-stuttgart.de/js/headfoot.js")
\ No newline at end of file
+    script(src="/js/headfoot.js")
\ No newline at end of file
diff --git a/views/EN/project/mailinglists.pug b/views/EN/project/mailinglists.pug
index f2ddbd8..75bc8de 100644
--- a/views/EN/project/mailinglists.pug
+++ b/views/EN/project/mailinglists.pug
@@ -58,4 +58,4 @@ html(lang="en")
     if isUserAuthenticated
         script(src="/js/headfootLogout.js")
     else
-        script(src="https://transfer.hft-stuttgart.de/js/headfoot.js")
\ No newline at end of file
+        script(src="/js/headfoot.js")
\ No newline at end of file
diff --git a/views/EN/project/projects.pug b/views/EN/project/projects.pug
index 56f65c1..b67bf11 100644
--- a/views/EN/project/projects.pug
+++ b/views/EN/project/projects.pug
@@ -114,4 +114,4 @@ html(lang="de")
     if isUserAuthenticated
         script(src="/js/headfootLogout.js")
     else
-        script(src="https://transfer.hft-stuttgart.de/js/headfoot.js")
\ No newline at end of file
+        script(src="/js/headfoot.js")
\ No newline at end of file
-- 
GitLab


From e6dd574de3eb0c6bc25ba9be1fcddfed0f6f5356 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Wed, 11 Nov 2020 17:28:55 +0100
Subject: [PATCH 02/13] fix 371

---
 views/DE/project/projectList.pug | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/views/DE/project/projectList.pug b/views/DE/project/projectList.pug
index 8a20b9d..e1bdb08 100644
--- a/views/DE/project/projectList.pug
+++ b/views/DE/project/projectList.pug
@@ -59,9 +59,10 @@ html(lang="de")
                             div(class="row")
                                 div(class="col-9")
                                     p(class="card-text") #{item.desc}
-                                div(class="col-3")
-                                    svg(class="bi bi-chevron-right", width="32", height="32", viewBox="0 0 20 20", fill="currentColor", xmlns="http://www.w3.org/2000/svg")
-                                        | <a xlink:href="#{item.weburl}" target="_blank"><path fill-rule="evenodd" d="M6.646 3.646a.5.5 0 01.708 0l6 6a.5.5 0 010 .708l-6 6a.5.5 0 01-.708-.708L12.293 10 6.646 4.354a.5.5 0 010-.708z"></path></a>
+                                a(href=item.weburl, style="text-decoration: none;", target="_blank")
+                                    div(class="col-3")
+                                        svg(class="bi bi-chevron-right", width="32", height="32", viewBox="0 0 20 20", fill="black", xmlns="http://www.w3.org/2000/svg")
+                                            | <path fill-rule="evenodd" d="M6.646 3.646a.5.5 0 01.708 0l6 6a.5.5 0 010 .708l-6 6a.5.5 0 01-.708-.708L12.293 10 6.646 4.354a.5.5 0 010-.708z"></path>
             | </div>
 
     // jQuery
-- 
GitLab


From ca153d1e122b82e38fa41eb9ead8e2b8cbc72a62 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Wed, 11 Nov 2020 17:34:54 +0100
Subject: [PATCH 03/13] fix 373

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

diff --git a/views/DE/project/projectOverview.pug b/views/DE/project/projectOverview.pug
index 191db2b..c180b3e 100644
--- a/views/DE/project/projectOverview.pug
+++ b/views/DE/project/projectOverview.pug
@@ -21,7 +21,7 @@ html(lang="de")
                     h2(class="pt-4") Projektüberblick
                     p !{project.overview}
                     br
-                    b keywords:
+                    b keywords: &nbsp;
                     span #{project.keywords}
                     h2(class="pt-4") Fragestellung
                     p !{project.question}
-- 
GitLab


From 991066603b45d829effef257e6a7cb3a7ffe2d5d Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Wed, 11 Nov 2020 17:46:12 +0100
Subject: [PATCH 04/13] fix 371

---
 views/DE/project/pagesList.pug | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/views/DE/project/pagesList.pug b/views/DE/project/pagesList.pug
index 09a5215..cbbfca9 100644
--- a/views/DE/project/pagesList.pug
+++ b/views/DE/project/pagesList.pug
@@ -59,9 +59,10 @@ html(lang="de")
                             div(class="row")
                                 div(class="col-9")
                                     p(class="card-text") #{item.desc}
-                                div(class="col-3")
-                                    svg(class="bi bi-chevron-right", width="32", height="32", viewBox="0 0 20 20", fill="currentColor", xmlns="http://www.w3.org/2000/svg")
-                                        | <a xlink:href="#{item.weburl}" target="_blank"><path fill-rule="evenodd" d="M6.646 3.646a.5.5 0 01.708 0l6 6a.5.5 0 010 .708l-6 6a.5.5 0 01-.708-.708L12.293 10 6.646 4.354a.5.5 0 010-.708z"></path></a>
+                                a(href=item.weburl, style="text-decoration: none;", target="_blank")
+                                    div(class="col-3")
+                                        svg(class="bi bi-chevron-right", width="32", height="32", viewBox="0 0 20 20", fill="black", xmlns="http://www.w3.org/2000/svg")
+                                            | <path fill-rule="evenodd" d="M6.646 3.646a.5.5 0 01.708 0l6 6a.5.5 0 010 .708l-6 6a.5.5 0 01-.708-.708L12.293 10 6.646 4.354a.5.5 0 010-.708z"></path>
             | </div>
 
     // jQuery
-- 
GitLab


From 86f077fde2b44e7a69feaf5e46bb14eb2056f517 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Thu, 12 Nov 2020 16:34:47 +0100
Subject: [PATCH 05/13] MLAB-369: add bootsrap card-deck

---
 views/DE/project/pagesList.pug   | 2 +-
 views/DE/project/projectList.pug | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/views/DE/project/pagesList.pug b/views/DE/project/pagesList.pug
index cbbfca9..456760a 100644
--- a/views/DE/project/pagesList.pug
+++ b/views/DE/project/pagesList.pug
@@ -45,7 +45,7 @@ html(lang="de")
             p#pagesCounter #{pages.length} Projektinformationen werden angezeigt
             | <div class="row">
             for item in pages
-                div(class="py-4 col-sm")
+                div(class="card-deck py-4 col-sm")
                     div(class="card", style="width: 18rem;")
                         div(class="title-container")
                             h5(class="card-title-bottom-left") #{item.name}
diff --git a/views/DE/project/projectList.pug b/views/DE/project/projectList.pug
index e1bdb08..9d824a4 100644
--- a/views/DE/project/projectList.pug
+++ b/views/DE/project/projectList.pug
@@ -45,7 +45,7 @@ html(lang="de")
             p#projectCounter #{project.length} Projektdaten werden angezeigt
             | <div class="row">
             for item in project
-                div(class="py-4 col-sm")
+                div(class="card-deck py-4 col-sm")
                     div(class="card", style="width: 18rem;")
                         div(class="title-container")
                             h5(class="card-title-bottom-left") #{item.name}
-- 
GitLab


From 615f43e433c677d3a12be965b6919883942e976e Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Thu, 28 Jan 2021 17:55:55 +0100
Subject: [PATCH 06/13] update depedencies

---
 package-lock.json | 12 ++++++------
 package.json      |  5 ++---
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 0cb0d6a..9a9064e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -72,9 +72,9 @@
       "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw=="
     },
     "axios": {
-      "version": "0.20.0",
-      "resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz",
-      "integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==",
+      "version": "0.21.1",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
+      "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
       "requires": {
         "follow-redirects": "^1.10.0"
       }
@@ -520,9 +520,9 @@
       }
     },
     "follow-redirects": {
-      "version": "1.13.0",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz",
-      "integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA=="
+      "version": "1.13.2",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.2.tgz",
+      "integrity": "sha512-6mPTgLxYm3r6Bkkg0vNM0HTjfGrOEtsfbhagQvbxDEsEkpNhw582upBaoRZylzen6krEmxXJgt9Ju6HiI4O7BA=="
     },
     "forwarded": {
       "version": "0.1.2",
diff --git a/package.json b/package.json
index 0838772..7064bcc 100644
--- a/package.json
+++ b/package.json
@@ -7,8 +7,7 @@
     "email": "rosanny.sihombing@hft-stuttgart.de"
   },
   "keywords": [
-    "m4_lab",
-    "prjects"
+    "m4_lab"
   ],
   "repository": {
     "type": "git",
@@ -20,7 +19,7 @@
   },
   "dependencies": {
     "async": "^3.2.0",
-    "axios": "^0.20.0",
+    "axios": "^0.21.1",
     "body-parser": "^1.19.0",
     "compression": "^1.7.4",
     "cookie-parser": "1.4.3",
-- 
GitLab


From 9d64c450e157b5a7b4ceb53b1cd0220fd7916789 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Thu, 28 Jan 2021 17:57:14 +0100
Subject: [PATCH 07/13] remove unused codes and add bug fixing

---
 routes/gitlab.js         |  81 ++++++++++++
 routes/routes-project.js | 261 +++++++++++----------------------------
 2 files changed, 154 insertions(+), 188 deletions(-)
 create mode 100644 routes/gitlab.js

diff --git a/routes/gitlab.js b/routes/gitlab.js
new file mode 100644
index 0000000..be92ac5
--- /dev/null
+++ b/routes/gitlab.js
@@ -0,0 +1,81 @@
+var env = process.env.NODE_ENV || 'testing'
+const config = require('../config/config')[env]
+const axios = require('axios')
+
+var gitlab = {
+    getRepos: async function(perPage, idAfter) {
+        try {
+            let projects = await axios({
+                method: 'get',
+                url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/projects?visibility=public&pagination=keyset&per_page='+perPage+'&order_by=id&sort=asc&id_after='+idAfter
+            })
+            let data = projects.data
+            let reposArr = []
+            for(let i = 0; i < data.length; i++){
+                // skip template project
+                if (data[i].name == 'template_gitlab_page') {
+                    continue
+                } else if(!data[i].tag_list.includes('website')) {
+                    reposArr.push(data[i])
+                }
+            }
+            return {
+                error: false,
+                data: reposArr}
+        }
+        catch (err) {
+            return {
+                error: true,
+                data: err}
+        }
+    },
+    getPages: async function(perPage, idAfter) {
+        try {
+            let projects = await axios({
+                method: 'get',
+                url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/projects?visibility=public&pagination=keyset&per_page='+perPage+'&order_by=id&sort=asc&id_after='+idAfter
+            })
+            let data = projects.data
+            let pagesArr = []
+            for(let i = 0; i < data.length; i++){
+                // skip template project
+                if (data[i].name == 'template_gitlab_page') {
+                    continue
+                } else if(data[i].tag_list.includes('website')) {
+                    pagesArr.push(data[i])
+                }
+            }
+            return {
+                error: false,
+                data: pagesArr}
+        }
+        catch (err) {
+            return {
+                error: true,
+                data: err}
+        }
+    },
+    getProjectsFromRunners: async function() {
+        try {
+            let runner = await axios({
+                method: 'get',
+                url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/runners/7',
+                headers: { 
+                    'Authorization': 'Bearer '+config.gitlab.token_readWriteProjects
+                }
+            })
+            let runnerProjects = runner.data.projects
+            return {
+                error: false,
+                data: runnerProjects
+            }
+        }
+        catch (err) {
+            return {
+                error: true,
+                data: err}
+        }
+    }
+}
+
+module.exports = gitlab
\ No newline at end of file
diff --git a/routes/routes-project.js b/routes/routes-project.js
index 65d942a..3bf97e2 100644
--- a/routes/routes-project.js
+++ b/routes/routes-project.js
@@ -1,7 +1,6 @@
-const fs = require('fs')
 //const SamlStrategy = require('passport-saml').Strategy
-const dbconn = require('./dbconn')
 const methods = require('./methods')
+const gitlab = require('./gitlab')
 // pwd encryption
 //const bcrypt = require('bcryptjs');
 //const saltRounds = 10;
@@ -10,10 +9,8 @@ const methods = require('./methods')
 const async = require('async')
 //const crypto = require('crypto')
 //const mailer = require('./mailer')
-
 const helpers = require('./helpers')
 const pictSizeLimit = 1000000 // 1 MB
-const axios = require('axios')
 
 module.exports = function (app) {
  
@@ -53,59 +50,6 @@ module.exports = function (app) {
     ])
   })
 
-  app.get('/project_', function (req, res) {
-    async.waterfall([
-      // get all projects from projectdb
-      function(done) {
-        methods.getAllProjects(function(projectsOverview, err) {
-          if (!err) {
-            done(err, projectsOverview)
-          }
-        })
-      },
-      // create JSON object for front-end
-      function(projectsOverview, done) {
-        var activeProjects = []
-        var nonActiveProjects = []
-
-        for (var i = 0; i < projectsOverview.length; i++) {
-          var project = {
-            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,
-            gitlab: projectsOverview[i].gitlab
-          }
-          if (projectsOverview[i].projectstatus == 0) {
-            nonActiveProjects.push(project)
-          }
-          else if (projectsOverview[i].projectstatus == 1) {
-            activeProjects.push(project)
-          }
-        }
-
-        // render the page
-        if (req.isAuthenticated()) {
-          res.render(lang+'/project/projects', {
-            isUserAuthenticated: true,
-            nonActive: nonActiveProjects,
-            active: activeProjects
-          });
-        }
-        else {
-          res.render(lang+'/project/projects', {
-            isUserAuthenticated: false,
-            nonActive: nonActiveProjects,
-            active: activeProjects
-          });
-        }
-      }
-    ])
-  })
-
   app.get('/', function (req, res) {
     res.render(lang+'/project/project-simplified', {
        isUserAuthenticated: req.isAuthenticated(),
@@ -121,52 +65,6 @@ module.exports = function (app) {
       res.redirect('/login')
     }
   })
-  
-  app.post('/addprojectoverview__', function (req, res) {
-    if (req.isAuthenticated()) {
-      var wiki = 0
-      if (req.body.wiki)
-        wiki = 1
-
-      var projectTerm = req.body.termForm + " - " + req.body.termTo
-      var projectOverviewData = {
-        pname: req.body.pname,
-        title: req.body.title,
-        onelinesummary: req.body.summary,
-        category: req.body.category,
-        logo: 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: projectTerm,
-        further_details: req.body.furtherDetails,
-        website: req.body.website,
-        src: req.body.src,
-        caption: req.body.caption,
-        contact_lastname: req.body.contactName,
-        contact_email: req.body.contactEmail,
-        leader_lastname: req.body.leaderName,
-        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');
-        }
-      })
-    }
-  })
 
   app.post('/addprojectoverview', function (req, res) {
     if (req.isAuthenticated()) {
@@ -304,10 +202,6 @@ module.exports = function (app) {
     }
   })
 
-  app.get('/updateprojectoverview', function (req, res) {
-    // only their own project
-  })
-
   app.post('/updateprojectoverview', function (req, res) {
     // only their own project
   })
@@ -356,12 +250,6 @@ module.exports = function (app) {
     ])
   })
 
-  async function getProjectsFromGitlab(perPage, idAfter) {
-    // public projects
-    return await axios.get('https://transfer.hft-stuttgart.de/gitlab/api/v4/projects?visibility=public&pagination=keyset&per_page='+
-      perPage+'&order_by=id&sort=asc&id_after='+idAfter)
-  }
-
   // Projektdaten
   app.get('/projektdaten', async function(req, res){
     let projectArr = []
@@ -369,7 +257,7 @@ module.exports = function (app) {
     let firstId = 0
 
     while (isProject == true) {
-      let projects = await getProjectsFromGitlab(10, firstId)
+      let projects = await gitlab.getRepos(100, firstId)
       let projectData = projects.data
 
       if (projectData.length == 0) {
@@ -377,32 +265,24 @@ module.exports = function (app) {
       }
       else {
         for(let i = 0; i < projectData.length; i++){
-          // skip template project
-          if (projectData[i].name == "template_gitlab_page") {
-            continue
+          // M4_LAB logo for all projects that do not have logo
+          if (projectData[i].avatar_url == null) {
+            projectData[i].avatar_url = "https://m4lab.hft-stuttgart.de/img/footer/M4_LAB_LOGO_Graustufen.png"
+          }
+          // for all projects that have no description
+          if (projectData[i].description == "") {
+            projectData[i].description = "- no description -"
           }
-          // only repo
-          if (!projectData[i].tag_list.includes('website')) {
-            // M4_LAB logo for all projects that do not have logo
-            if (projectData[i].avatar_url == null) {
-              projectData[i].avatar_url = "https://m4lab.hft-stuttgart.de/img/footer/M4_LAB_LOGO_Graustufen.png"
-            }
-            // for all projects that have no description
-            if (projectData[i].description == "") {
-              projectData[i].description = "- no description -"
-            }
 
-            let project = {
-              logo: projectData[i].avatar_url,
-              name: projectData[i].name,
-              weburl: projectData[i].web_url,
-              desc: projectData[i].description,
-              keywords: projectData[i].tag_list
-            }
-            projectArr.push(project)
+          let project = {
+            logo: projectData[i].avatar_url,
+            name: projectData[i].name,
+            weburl: projectData[i].web_url,
+            desc: projectData[i].description,
+            keywords: projectData[i].tag_list
           }
+          projectArr.push(project)
         }
-
         firstId = projectData[projectData.length-1].id
       }
     }
@@ -418,63 +298,68 @@ module.exports = function (app) {
     let isProject = true
     let firstId = 0
 
-    while (isProject == true) {
-      let projects = await getProjectsFromGitlab(10, firstId)
-      let projectData = projects.data
-
-      if (projectData.length == 0) {
-        isProject = false
+    let runnerProjects = await gitlab.getProjectsFromRunners()
+    if(runnerProjects.error) {
+      // error response: to be updated
+      res.status(500).render(lang+'/500', { error: err })
+    } else {
+      let runnerProjectsData = runnerProjects.data
+      let runnerProjectsIds = [] 
+      for(let i = 0; i < runnerProjectsData.length; i++){
+        runnerProjectsIds.push(runnerProjectsData[i].id)
       }
-      else {
-        for(let i = 0; i < projectData.length; i++){
-          // skip template project
-          if (projectData[i].name == "template_gitlab_page") {
-            continue
-          }
-          // websites
-          if (projectData[i].tag_list.includes('website')) {
-            // M4_LAB logo for all projects that do not have logo
-            if (projectData[i].avatar_url == null) {
-              projectData[i].avatar_url = "https://m4lab.hft-stuttgart.de/img/footer/M4_LAB_LOGO_Graustufen.png"
-            }
-            // for all projects that have no description
-            if (projectData[i].description == "") {
-              projectData[i].description = "- no description -"
-            }
-            // customize website name
-            if (projectData[i].name == "Visualization") {
-              projectData[i].web_url = "https://transfer.hft-stuttgart.de/pages/visualization"
-            }
-            else if (projectData[i].name == "IN-Source") {
-              projectData[i].web_url = "https://transfer.hft-stuttgart.de/pages/INsource"
-            }
-            else if (projectData[i].name == "3DS_Visualization_Cesium") {
-              projectData[i].web_url = "https://transfer.hft-stuttgart.de/pages/3ds_visualization_cesium"
-            }
-            else {
-              projectData[i].web_url = "https://transfer.hft-stuttgart.de/pages/"+projectData[i].name
-            }
-            // remove 'website' from tag list
-            const index = projectData[i].tag_list.indexOf('website');
-            if (index > -1) {
-              projectData[i].tag_list.splice(index, 1);
-            }
 
-            // fill in pagesArr
-            let pages = {
-              logo: projectData[i].avatar_url,
-              name: projectData[i].name,
-              weburl: projectData[i].web_url,
-              desc: projectData[i].description,
-              keywords: projectData[i].tag_list
+      while (isProject == true) {
+        let pages = await gitlab.getPages(100, firstId)
+        let pagesData = pages.data
+
+        if (pagesData.length == 0) {
+          isProject = false
+        } else {
+          for(let i = 0; i < pagesData.length; i++){
+            //  ONLY IF THE PROJECT IS AVAILABLE IN THE RUNNER
+            if(runnerProjectsIds.indexOf(pagesData[i].id) > -1) {
+              // M4_LAB logo for all projects that do not have logo
+              if (pagesData[i].avatar_url == null) {
+                pagesData[i].avatar_url = "https://m4lab.hft-stuttgart.de/img/footer/M4_LAB_LOGO_Graustufen.png"
+              }
+              // for all projects that have no description
+              if (pagesData[i].description == "") {
+                pagesData[i].description = "- no description -"
+              }
+              // customize website name
+              if (pagesData[i].name == "Visualization") {
+                pagesData[i].web_url = "https://transfer.hft-stuttgart.de/pages/visualization"
+              }
+              else if (pagesData[i].name == "IN-Source") {
+                pagesData[i].web_url = "https://transfer.hft-stuttgart.de/pages/INsource"
+              }
+              else if (pagesData[i].name == "3DS_Visualization_Cesium") {
+                pagesData[i].web_url = "https://transfer.hft-stuttgart.de/pages/3ds_visualization_cesium"
+              }
+              else {
+                pagesData[i].web_url = "https://transfer.hft-stuttgart.de/pages/"+pagesData[i].name
+              }
+              // remove 'website' from tag list
+              let index = pagesData[i].tag_list.indexOf('website')
+              if (index > -1) {
+                pagesData[i].tag_list.splice(index, 1)
+              }
+
+              // fill in pagesArr
+              let pages = {
+                logo: pagesData[i].avatar_url,
+                name: pagesData[i].name,
+                weburl: pagesData[i].web_url,
+                desc: pagesData[i].description,
+                keywords: pagesData[i].tag_list
+              }
+              pagesArr.push(pages)
             }
-            pagesArr.push(pages)
-
           }
+          firstId = pagesData[pagesData.length-1].id
         }
-
-        firstId = projectData[projectData.length-1].id
-      }
+      }        
     }
 
     res.render(lang+'/project/pagesList', {
-- 
GitLab


From 42f3c1d04ad3df2b81baca2a72732f6b4626c244 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Wed, 3 Feb 2021 11:18:20 +0100
Subject: [PATCH 08/13] remote unused lines

---
 app.js | 2 --
 1 file changed, 2 deletions(-)

diff --git a/app.js b/app.js
index e7eeac4..996640b 100644
--- a/app.js
+++ b/app.js
@@ -55,12 +55,10 @@ app.use(function(req, res, next) {
     next()
 })
   
-//require('./routes/routes-account')(app, config, passport, i18n);
 require('./routes/routes-project')(app, config, passport)
   
 // Handle 404
 app.use(function (req, res, next) {
-    //res.status(404).send('404: Page not Found', 404)
     res.status(404).render('./DE/404')
 })
   
-- 
GitLab


From d79ce45aacf3c3ea6fcd36163c077768bdd29c38 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Wed, 3 Feb 2021 11:19:20 +0100
Subject: [PATCH 09/13] add gitlab configuration parameter

---
 config/config.js | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/config/config.js b/config/config.js
index 8fa365a..a8bbdb3 100644
--- a/config/config.js
+++ b/config/config.js
@@ -29,6 +29,9 @@ module.exports = {
       authPass: 'passwordmail',
       tlsCiphers: 'SSLv3',
       from: 'email_from',
+    },
+    gitlab: {
+      token_readWriteProjects: 'putyourtokenhere'
     }
   },
   testing: {
@@ -61,6 +64,9 @@ module.exports = {
       authPass: 'passwordmail',
       tlsCiphers: 'SSLv3',
       from: 'email_from',
+    },
+    gitlab: {
+      token_readWriteProjects: 'putyourtokenhere'
     }
   },
   production: {
-- 
GitLab


From 6d5883ce8fae4c704701feecfc183dbea289b095 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Thu, 18 Mar 2021 20:12:50 +0100
Subject: [PATCH 10/13] fixing vulnerabilities

---
 package-lock.json | 570 ++++++++++++++++++----------------------------
 package.json      |   4 +-
 2 files changed, 218 insertions(+), 356 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 9a9064e..0e4f3c4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4,17 +4,24 @@
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
-    "@types/babel-types": {
-      "version": "7.0.7",
-      "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.7.tgz",
-      "integrity": "sha512-dBtBbrc+qTHy1WdfHYjBwRln4+LWqASWakLHsWHR2NWHIFkv4W3O070IGoGLEBrJBvct3r0L1BUPuvURi7kYUQ=="
-    },
-    "@types/babylon": {
-      "version": "6.16.5",
-      "resolved": "https://registry.npmjs.org/@types/babylon/-/babylon-6.16.5.tgz",
-      "integrity": "sha512-xH2e58elpj1X4ynnKp9qSnWlsRTIs6n3tgLGNfwAGHwePw0mulHQllV34n0T25uYSu1k0hRKkWXF890B1yS47w==",
+    "@babel/helper-validator-identifier": {
+      "version": "7.12.11",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz",
+      "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw=="
+    },
+    "@babel/parser": {
+      "version": "7.13.11",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.11.tgz",
+      "integrity": "sha512-PhuoqeHoO9fc4ffMEVk4qb/w/s2iOSWohvbHxLtxui0eBg3Lg5gN1U8wp1V1u61hOWkPQJJyJzGH6Y+grwkq8Q=="
+    },
+    "@babel/types": {
+      "version": "7.13.0",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.0.tgz",
+      "integrity": "sha512-hE+HE8rnG1Z6Wzo+MhaKE5lM5eMx71T4EHJgku2E3xIfaULhDcxiiRxUYgwX8qwP1BBSlag+TdGOt6JAidIZTA==",
       "requires": {
-        "@types/babel-types": "*"
+        "@babel/helper-validator-identifier": "^7.12.11",
+        "lodash": "^4.17.19",
+        "to-fast-properties": "^2.0.0"
       }
     },
     "accepts": {
@@ -27,34 +34,9 @@
       }
     },
     "acorn": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
-      "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo="
-    },
-    "acorn-globals": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz",
-      "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=",
-      "requires": {
-        "acorn": "^4.0.4"
-      },
-      "dependencies": {
-        "acorn": {
-          "version": "4.0.13",
-          "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
-          "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c="
-        }
-      }
-    },
-    "align-text": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
-      "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
-      "requires": {
-        "kind-of": "^3.0.2",
-        "longest": "^1.0.1",
-        "repeat-string": "^1.5.2"
-      }
+      "version": "7.4.1",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+      "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A=="
     },
     "array-flatten": {
       "version": "1.1.1",
@@ -66,6 +48,11 @@
       "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
       "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
     },
+    "assert-never": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz",
+      "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw=="
+    },
     "async": {
       "version": "3.2.0",
       "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz",
@@ -79,38 +66,14 @@
         "follow-redirects": "^1.10.0"
       }
     },
-    "babel-runtime": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
-      "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+    "babel-walk": {
+      "version": "3.0.0-canary-5",
+      "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz",
+      "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==",
       "requires": {
-        "core-js": "^2.4.0",
-        "regenerator-runtime": "^0.11.0"
+        "@babel/types": "^7.9.6"
       }
     },
-    "babel-types": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
-      "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
-      "requires": {
-        "babel-runtime": "^6.26.0",
-        "esutils": "^2.0.2",
-        "lodash": "^4.17.4",
-        "to-fast-properties": "^1.0.3"
-      },
-      "dependencies": {
-        "lodash": {
-          "version": "4.17.19",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
-          "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ=="
-        }
-      }
-    },
-    "babylon": {
-      "version": "6.18.0",
-      "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
-      "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ=="
-    },
     "basic-auth": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
@@ -159,25 +122,20 @@
       "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
       "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
     },
-    "camelcase": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
-      "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk="
+    "call-bind": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+      "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+      "requires": {
+        "function-bind": "^1.1.1",
+        "get-intrinsic": "^1.0.2"
+      }
     },
     "camelize": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz",
       "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs="
     },
-    "center-align": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
-      "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
-      "requires": {
-        "align-text": "^0.1.3",
-        "lazy-cache": "^1.0.3"
-      }
-    },
     "character-parser": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz",
@@ -186,24 +144,6 @@
         "is-regex": "^1.0.3"
       }
     },
-    "clean-css": {
-      "version": "4.2.3",
-      "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz",
-      "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==",
-      "requires": {
-        "source-map": "~0.6.0"
-      }
-    },
-    "cliui": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
-      "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
-      "requires": {
-        "center-align": "^0.1.1",
-        "right-align": "^0.1.1",
-        "wordwrap": "0.0.2"
-      }
-    },
     "compressible": {
       "version": "2.0.18",
       "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
@@ -264,14 +204,12 @@
       "integrity": "sha1-2GMPJtlaf4UfmVax6MxnMvO2qjA="
     },
     "constantinople": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-3.1.2.tgz",
-      "integrity": "sha512-yePcBqEFhLOqSBtwYOGGS1exHo/s1xjekXiinh4itpNQGCu4KA1euPh1fg07N2wMITZXQkBz75Ntdt1ctGZouw==",
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz",
+      "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==",
       "requires": {
-        "@types/babel-types": "^7.0.0",
-        "@types/babylon": "^6.16.2",
-        "babel-types": "^6.26.0",
-        "babylon": "^6.18.0"
+        "@babel/parser": "^7.6.0",
+        "@babel/types": "^7.6.1"
       }
     },
     "content-disposition": {
@@ -311,11 +249,6 @@
       "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
       "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
     },
-    "core-js": {
-      "version": "2.6.11",
-      "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz",
-      "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg=="
-    },
     "core-util-is": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
@@ -341,11 +274,6 @@
         }
       }
     },
-    "decamelize": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
-      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
-    },
     "depd": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
@@ -398,11 +326,6 @@
       "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
       "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
     },
-    "esutils": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
-      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
-    },
     "etag": {
       "version": "1.8.1",
       "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
@@ -544,6 +467,16 @@
       "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
       "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
     },
+    "get-intrinsic": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+      "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+      "requires": {
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1"
+      }
+    },
     "has": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
@@ -552,6 +485,11 @@
         "function-bind": "^1.1.1"
       }
     },
+    "has-symbols": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
+      "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw=="
+    },
     "helmet": {
       "version": "3.23.3",
       "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.23.3.tgz",
@@ -650,38 +588,35 @@
       "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
       "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
     },
-    "is-buffer": {
-      "version": "1.1.6",
-      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
-      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
+    "is-core-module": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz",
+      "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==",
+      "requires": {
+        "has": "^1.0.3"
+      }
     },
     "is-expression": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-3.0.0.tgz",
-      "integrity": "sha1-Oayqa+f9HzRx3ELHQW5hwkMXrJ8=",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz",
+      "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==",
       "requires": {
-        "acorn": "~4.0.2",
-        "object-assign": "^4.0.1"
-      },
-      "dependencies": {
-        "acorn": {
-          "version": "4.0.13",
-          "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
-          "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c="
-        }
+        "acorn": "^7.1.1",
+        "object-assign": "^4.1.1"
       }
     },
     "is-promise": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
-      "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o="
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
+      "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="
     },
     "is-regex": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
-      "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz",
+      "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==",
       "requires": {
-        "has": "^1.0.1"
+        "call-bind": "^1.0.2",
+        "has-symbols": "^1.0.1"
       }
     },
     "isarray": {
@@ -703,23 +638,10 @@
         "promise": "^7.0.1"
       }
     },
-    "kind-of": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
-      "requires": {
-        "is-buffer": "^1.1.5"
-      }
-    },
-    "lazy-cache": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
-      "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4="
-    },
-    "longest": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
-      "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc="
+    "lodash": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
     },
     "media-typer": {
       "version": "0.3.0",
@@ -858,26 +780,25 @@
       }
     },
     "passport-saml": {
-      "version": "1.3.4",
-      "resolved": "https://registry.npmjs.org/passport-saml/-/passport-saml-1.3.4.tgz",
-      "integrity": "sha512-FYkRAt3pbmUpm/FsH97U/xYDnd1+z3FuGYe3IUOQPRgyoDg2ub8LYofst4UU49u65aAWHHSfXk6S3CdSMllq3A==",
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/passport-saml/-/passport-saml-2.0.6.tgz",
+      "integrity": "sha512-oxcL1R+4zhn7m0V7Ik5z8Cy51FTyuEjyjxYZkUzuZ9wA2Trv2ikJljS0bEBv0UO22SgXZ7TvXKGXm/snxiaevg==",
       "requires": {
-        "debug": "^3.1.0",
+        "debug": "^4.3.1",
         "passport-strategy": "*",
-        "q": "^1.5.0",
-        "xml-crypto": "^1.4.0",
-        "xml-encryption": "^1.0.0",
-        "xml2js": "0.4.x",
-        "xmlbuilder": "^11.0.0",
-        "xmldom": "0.1.x"
+        "xml-crypto": "^2.0.0",
+        "xml-encryption": "1.2.1",
+        "xml2js": "^0.4.23",
+        "xmlbuilder": "^15.1.1",
+        "xmldom": "0.5.x"
       },
       "dependencies": {
         "debug": {
-          "version": "3.2.6",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
-          "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+          "version": "4.3.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+          "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
           "requires": {
-            "ms": "^2.1.1"
+            "ms": "2.1.2"
           }
         }
       }
@@ -925,123 +846,116 @@
       }
     },
     "pug": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/pug/-/pug-2.0.4.tgz",
-      "integrity": "sha512-XhoaDlvi6NIzL49nu094R2NA6P37ijtgMDuWE+ofekDChvfKnzFal60bhSdiy8y2PBO6fmz3oMEIcfpBVRUdvw==",
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.2.tgz",
+      "integrity": "sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==",
       "requires": {
-        "pug-code-gen": "^2.0.2",
-        "pug-filters": "^3.1.1",
-        "pug-lexer": "^4.1.0",
-        "pug-linker": "^3.0.6",
-        "pug-load": "^2.0.12",
-        "pug-parser": "^5.0.1",
-        "pug-runtime": "^2.0.5",
-        "pug-strip-comments": "^1.0.4"
+        "pug-code-gen": "^3.0.2",
+        "pug-filters": "^4.0.0",
+        "pug-lexer": "^5.0.1",
+        "pug-linker": "^4.0.0",
+        "pug-load": "^3.0.0",
+        "pug-parser": "^6.0.0",
+        "pug-runtime": "^3.0.1",
+        "pug-strip-comments": "^2.0.0"
       }
     },
     "pug-attrs": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-2.0.4.tgz",
-      "integrity": "sha512-TaZ4Z2TWUPDJcV3wjU3RtUXMrd3kM4Wzjbe3EWnSsZPsJ3LDI0F3yCnf2/W7PPFF+edUFQ0HgDL1IoxSz5K8EQ==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz",
+      "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==",
       "requires": {
-        "constantinople": "^3.0.1",
-        "js-stringify": "^1.0.1",
-        "pug-runtime": "^2.0.5"
+        "constantinople": "^4.0.1",
+        "js-stringify": "^1.0.2",
+        "pug-runtime": "^3.0.0"
       }
     },
     "pug-code-gen": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-2.0.2.tgz",
-      "integrity": "sha512-kROFWv/AHx/9CRgoGJeRSm+4mLWchbgpRzTEn8XCiwwOy6Vh0gAClS8Vh5TEJ9DBjaP8wCjS3J6HKsEsYdvaCw==",
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.2.tgz",
+      "integrity": "sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==",
       "requires": {
-        "constantinople": "^3.1.2",
+        "constantinople": "^4.0.1",
         "doctypes": "^1.1.0",
-        "js-stringify": "^1.0.1",
-        "pug-attrs": "^2.0.4",
-        "pug-error": "^1.3.3",
-        "pug-runtime": "^2.0.5",
-        "void-elements": "^2.0.1",
-        "with": "^5.0.0"
+        "js-stringify": "^1.0.2",
+        "pug-attrs": "^3.0.0",
+        "pug-error": "^2.0.0",
+        "pug-runtime": "^3.0.0",
+        "void-elements": "^3.1.0",
+        "with": "^7.0.0"
       }
     },
     "pug-error": {
-      "version": "1.3.3",
-      "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-1.3.3.tgz",
-      "integrity": "sha512-qE3YhESP2mRAWMFJgKdtT5D7ckThRScXRwkfo+Erqga7dyJdY3ZquspprMCj/9sJ2ijm5hXFWQE/A3l4poMWiQ=="
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz",
+      "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ=="
     },
     "pug-filters": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-3.1.1.tgz",
-      "integrity": "sha512-lFfjNyGEyVWC4BwX0WyvkoWLapI5xHSM3xZJFUhx4JM4XyyRdO8Aucc6pCygnqV2uSgJFaJWW3Ft1wCWSoQkQg==",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz",
+      "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==",
       "requires": {
-        "clean-css": "^4.1.11",
-        "constantinople": "^3.0.1",
+        "constantinople": "^4.0.1",
         "jstransformer": "1.0.0",
-        "pug-error": "^1.3.3",
-        "pug-walk": "^1.1.8",
-        "resolve": "^1.1.6",
-        "uglify-js": "^2.6.1"
+        "pug-error": "^2.0.0",
+        "pug-walk": "^2.0.0",
+        "resolve": "^1.15.1"
       }
     },
     "pug-lexer": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-4.1.0.tgz",
-      "integrity": "sha512-i55yzEBtjm0mlplW4LoANq7k3S8gDdfC6+LThGEvsK4FuobcKfDAwt6V4jKPH9RtiE3a2Akfg5UpafZ1OksaPA==",
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz",
+      "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==",
       "requires": {
-        "character-parser": "^2.1.1",
-        "is-expression": "^3.0.0",
-        "pug-error": "^1.3.3"
+        "character-parser": "^2.2.0",
+        "is-expression": "^4.0.0",
+        "pug-error": "^2.0.0"
       }
     },
     "pug-linker": {
-      "version": "3.0.6",
-      "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-3.0.6.tgz",
-      "integrity": "sha512-bagfuHttfQOpANGy1Y6NJ+0mNb7dD2MswFG2ZKj22s8g0wVsojpRlqveEQHmgXXcfROB2RT6oqbPYr9EN2ZWzg==",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz",
+      "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==",
       "requires": {
-        "pug-error": "^1.3.3",
-        "pug-walk": "^1.1.8"
+        "pug-error": "^2.0.0",
+        "pug-walk": "^2.0.0"
       }
     },
     "pug-load": {
-      "version": "2.0.12",
-      "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-2.0.12.tgz",
-      "integrity": "sha512-UqpgGpyyXRYgJs/X60sE6SIf8UBsmcHYKNaOccyVLEuT6OPBIMo6xMPhoJnqtB3Q3BbO4Z3Bjz5qDsUWh4rXsg==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz",
+      "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==",
       "requires": {
-        "object-assign": "^4.1.0",
-        "pug-walk": "^1.1.8"
+        "object-assign": "^4.1.1",
+        "pug-walk": "^2.0.0"
       }
     },
     "pug-parser": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-5.0.1.tgz",
-      "integrity": "sha512-nGHqK+w07p5/PsPIyzkTQfzlYfuqoiGjaoqHv1LjOv2ZLXmGX1O+4Vcvps+P4LhxZ3drYSljjq4b+Naid126wA==",
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz",
+      "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==",
       "requires": {
-        "pug-error": "^1.3.3",
-        "token-stream": "0.0.1"
+        "pug-error": "^2.0.0",
+        "token-stream": "1.0.0"
       }
     },
     "pug-runtime": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-2.0.5.tgz",
-      "integrity": "sha512-P+rXKn9un4fQY77wtpcuFyvFaBww7/91f3jHa154qU26qFAnOe6SW1CbIDcxiG5lLK9HazYrMCCuDvNgDQNptw=="
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz",
+      "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg=="
     },
     "pug-strip-comments": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-1.0.4.tgz",
-      "integrity": "sha512-i5j/9CS4yFhSxHp5iKPHwigaig/VV9g+FgReLJWWHEHbvKsbqL0oP/K5ubuLco6Wu3Kan5p7u7qk8A4oLLh6vw==",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz",
+      "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==",
       "requires": {
-        "pug-error": "^1.3.3"
+        "pug-error": "^2.0.0"
       }
     },
     "pug-walk": {
-      "version": "1.1.8",
-      "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-1.1.8.tgz",
-      "integrity": "sha512-GMu3M5nUL3fju4/egXwZO0XLi6fW/K3T3VTgFQ14GxNi8btlxgT5qZL//JwZFm/2Fa64J/PNS8AZeys3wiMkVA=="
-    },
-    "q": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
-      "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc="
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz",
+      "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ=="
     },
     "qs": {
       "version": "6.7.0",
@@ -1074,32 +988,15 @@
       "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.2.0.tgz",
       "integrity": "sha512-LgQJIuS6nAy1Jd88DCQRemyE3mS+ispwlqMk3b0yjZ257fI1v9c+/p6SD5gP5FGyXUIgrNOAfmyioHwZtYv2VA=="
     },
-    "regenerator-runtime": {
-      "version": "0.11.1",
-      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
-      "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
-    },
-    "repeat-string": {
-      "version": "1.6.1",
-      "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
-      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
-    },
     "resolve": {
-      "version": "1.15.1",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz",
-      "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==",
+      "version": "1.20.0",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
+      "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
       "requires": {
+        "is-core-module": "^2.2.0",
         "path-parse": "^1.0.6"
       }
     },
-    "right-align": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
-      "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
-      "requires": {
-        "align-text": "^0.1.1"
-      }
-    },
     "safe-buffer": {
       "version": "5.1.2",
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
@@ -1158,11 +1055,6 @@
       "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
       "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
     },
-    "source-map": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
-    },
     "sqlstring": {
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
@@ -1187,9 +1079,9 @@
       }
     },
     "to-fast-properties": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
-      "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc="
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+      "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4="
     },
     "toidentifier": {
       "version": "1.0.0",
@@ -1197,9 +1089,9 @@
       "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
     },
     "token-stream": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-0.0.1.tgz",
-      "integrity": "sha1-zu78cXp2xDFvEm0LnbqlXX598Bo="
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz",
+      "integrity": "sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ="
     },
     "type-is": {
       "version": "1.6.18",
@@ -1210,29 +1102,6 @@
         "mime-types": "~2.1.24"
       }
     },
-    "uglify-js": {
-      "version": "2.8.29",
-      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
-      "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
-      "requires": {
-        "source-map": "~0.5.1",
-        "uglify-to-browserify": "~1.0.0",
-        "yargs": "~3.10.0"
-      },
-      "dependencies": {
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
-        }
-      }
-    },
-    "uglify-to-browserify": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
-      "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
-      "optional": true
-    },
     "uid-safe": {
       "version": "2.1.5",
       "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
@@ -1262,48 +1131,33 @@
       "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
     },
     "void-elements": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
-      "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w="
-    },
-    "window-size": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
-      "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0="
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
+      "integrity": "sha1-YU9/v42AHwu18GYfWy9XhXUOTwk="
     },
     "with": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/with/-/with-5.1.1.tgz",
-      "integrity": "sha1-+k2qktrzLE6pTtRTyB8EaGtXXf4=",
+      "version": "7.0.2",
+      "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz",
+      "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==",
       "requires": {
-        "acorn": "^3.1.0",
-        "acorn-globals": "^3.0.0"
+        "@babel/parser": "^7.9.6",
+        "@babel/types": "^7.9.6",
+        "assert-never": "^1.2.1",
+        "babel-walk": "3.0.0-canary-5"
       }
     },
-    "wordwrap": {
-      "version": "0.0.2",
-      "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
-      "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8="
-    },
     "x-xss-protection": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.3.0.tgz",
       "integrity": "sha512-kpyBI9TlVipZO4diReZMAHWtS0MMa/7Kgx8hwG/EuZLiA6sg4Ah/4TRdASHhRRN3boobzcYgFRUFSgHRge6Qhg=="
     },
     "xml-crypto": {
-      "version": "1.5.3",
-      "resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-1.5.3.tgz",
-      "integrity": "sha512-uHkmpUtX15xExe5iimPmakAZN+6CqIvjmaJTy4FwqGzaTjrKRBNeqMh8zGEzVNgW0dk6beFYpyQSgqV/J6C5xA==",
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/xml-crypto/-/xml-crypto-2.1.1.tgz",
+      "integrity": "sha512-M+m4+HIJa83lu/CnspQjA7ap8gmanNDxxRjSisU8mPD4bqhxbo5N2bdpvG2WgVYOrPpOIOq55iY8Cz8Ai40IeQ==",
       "requires": {
-        "xmldom": "0.1.27",
-        "xpath": "0.0.27"
-      },
-      "dependencies": {
-        "xmldom": {
-          "version": "0.1.27",
-          "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz",
-          "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk="
-        }
+        "xmldom": "0.5.0",
+        "xpath": "0.0.32"
       }
     },
     "xml-encryption": {
@@ -1315,6 +1169,18 @@
         "node-forge": "^0.10.0",
         "xmldom": "~0.1.15",
         "xpath": "0.0.27"
+      },
+      "dependencies": {
+        "xmldom": {
+          "version": "0.1.31",
+          "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz",
+          "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ=="
+        },
+        "xpath": {
+          "version": "0.0.27",
+          "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.27.tgz",
+          "integrity": "sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ=="
+        }
       }
     },
     "xml2js": {
@@ -1324,33 +1190,29 @@
       "requires": {
         "sax": ">=0.6.0",
         "xmlbuilder": "~11.0.0"
+      },
+      "dependencies": {
+        "xmlbuilder": {
+          "version": "11.0.1",
+          "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+          "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="
+        }
       }
     },
     "xmlbuilder": {
-      "version": "11.0.1",
-      "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
-      "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="
+      "version": "15.1.1",
+      "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
+      "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="
     },
     "xmldom": {
-      "version": "0.1.31",
-      "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz",
-      "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ=="
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.5.0.tgz",
+      "integrity": "sha512-Foaj5FXVzgn7xFzsKeNIde9g6aFBxTPi37iwsno8QvApmtg7KYrr+OPyRHcJF7dud2a5nGRBXK3n0dL62Gf7PA=="
     },
     "xpath": {
-      "version": "0.0.27",
-      "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.27.tgz",
-      "integrity": "sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ=="
-    },
-    "yargs": {
-      "version": "3.10.0",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
-      "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
-      "requires": {
-        "camelcase": "^1.0.2",
-        "cliui": "^2.1.0",
-        "decamelize": "^1.0.0",
-        "window-size": "0.1.0"
-      }
+      "version": "0.0.32",
+      "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.32.tgz",
+      "integrity": "sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw=="
     }
   }
 }
diff --git a/package.json b/package.json
index 7064bcc..2b3eef7 100644
--- a/package.json
+++ b/package.json
@@ -33,8 +33,8 @@
     "morgan": "^1.10.0",
     "mysql": "^2.18.1",
     "passport": "0.3.2",
-    "passport-saml": "^1.3.4",
-    "pug": "^2.0.4"
+    "passport-saml": "^2.0.6",
+    "pug": "^3.0.2"
   },
   "engines": {
     "node": ">= 4.0.0"
-- 
GitLab


From e21da7e26ecb8ce53c175b61b64b64a0117146c0 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Fri, 19 Mar 2021 11:49:38 +0100
Subject: [PATCH 11/13] update css path

---
 views/DE/project/pagesList.pug   | 4 ++--
 views/DE/project/projectList.pug | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/views/DE/project/pagesList.pug b/views/DE/project/pagesList.pug
index 456760a..b690a89 100644
--- a/views/DE/project/pagesList.pug
+++ b/views/DE/project/pagesList.pug
@@ -4,8 +4,8 @@ html(lang="de")
     title= "Projektinformationen"
     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.min.css")
-    link(rel="stylesheet", type="text/css", href="https://transfer.hft-stuttgart.de/css/m4lab.css")
+    link(rel="stylesheet", type="text/css", href="/css/bootstrap.min.css")
+    link(rel="stylesheet", type="text/css", href="/css/m4lab.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.
         .title-container {
diff --git a/views/DE/project/projectList.pug b/views/DE/project/projectList.pug
index 9d824a4..c3af451 100644
--- a/views/DE/project/projectList.pug
+++ b/views/DE/project/projectList.pug
@@ -4,8 +4,8 @@ html(lang="de")
     title= "Projektdaten"
     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.min.css")
-    link(rel="stylesheet", type="text/css", href="https://transfer.hft-stuttgart.de/css/m4lab.css")
+    link(rel="stylesheet", type="text/css", href="/css/bootstrap.min.css")
+    link(rel="stylesheet", type="text/css", href="/css/m4lab.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.
         .title-container {
-- 
GitLab


From c0e9c9698c382925b2e1f1a9b3b2b615087598c5 Mon Sep 17 00:00:00 2001
From: Rosanny <rosanny.sihombing@hft-stuttgart.de>
Date: Fri, 19 Mar 2021 11:52:13 +0100
Subject: [PATCH 12/13] pulling gitlab pages without accessing runners

---
 routes/gitlab.js         |  62 +++++-----------------
 routes/routes-project.js | 110 ++++++++++++++++++---------------------
 2 files changed, 63 insertions(+), 109 deletions(-)

diff --git a/routes/gitlab.js b/routes/gitlab.js
index be92ac5..64b68af 100644
--- a/routes/gitlab.js
+++ b/routes/gitlab.js
@@ -1,9 +1,7 @@
-var env = process.env.NODE_ENV || 'testing'
-const config = require('../config/config')[env]
 const axios = require('axios')
 
 var gitlab = {
-    getRepos: async function(perPage, idAfter) {
+    getProjects: async function(perPage, idAfter) {
         try {
             let projects = await axios({
                 method: 'get',
@@ -11,43 +9,20 @@ var gitlab = {
             })
             let data = projects.data
             let reposArr = []
-            for(let i = 0; i < data.length; i++){
-                // skip template project
-                if (data[i].name == 'template_gitlab_page') {
-                    continue
-                } else if(!data[i].tag_list.includes('website')) {
-                    reposArr.push(data[i])
-                }
-            }
-            return {
-                error: false,
-                data: reposArr}
-        }
-        catch (err) {
-            return {
-                error: true,
-                data: err}
-        }
-    },
-    getPages: async function(perPage, idAfter) {
-        try {
-            let projects = await axios({
-                method: 'get',
-                url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/projects?visibility=public&pagination=keyset&per_page='+perPage+'&order_by=id&sort=asc&id_after='+idAfter
-            })
-            let data = projects.data
             let pagesArr = []
             for(let i = 0; i < data.length; i++){
                 // skip template project
-                if (data[i].name == 'template_gitlab_page') {
+                if (data[i].name == 'page_basic' || data[i].name == 'generic' || data[i].name == 'simple_raw' || data[i].name == 'simple_thesis') {
                     continue
                 } else if(data[i].tag_list.includes('website')) {
                     pagesArr.push(data[i])
+                } else {
+                    reposArr.push(data[i])
                 }
             }
             return {
                 error: false,
-                data: pagesArr}
+                data: [reposArr, pagesArr]}
         }
         catch (err) {
             return {
@@ -55,26 +30,13 @@ var gitlab = {
                 data: err}
         }
     },
-    getProjectsFromRunners: async function() {
-        try {
-            let runner = await axios({
-                method: 'get',
-                url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/runners/7',
-                headers: { 
-                    'Authorization': 'Bearer '+config.gitlab.token_readWriteProjects
-                }
-            })
-            let runnerProjects = runner.data.projects
-            return {
-                error: false,
-                data: runnerProjects
-            }
-        }
-        catch (err) {
-            return {
-                error: true,
-                data: err}
-        }
+    getLatestPipelineStatus: async function(projectId) {
+        return axios({
+            method: 'get',
+            url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/projects/'+projectId+'/pipelines'
+        })
+        .then(res => res.data[0].status)
+        .catch(err => console.error(err))
     }
 }
 
diff --git a/routes/routes-project.js b/routes/routes-project.js
index 3bf97e2..1dff948 100644
--- a/routes/routes-project.js
+++ b/routes/routes-project.js
@@ -257,8 +257,8 @@ module.exports = function (app) {
     let firstId = 0
 
     while (isProject == true) {
-      let projects = await gitlab.getRepos(100, firstId)
-      let projectData = projects.data
+      let projects = await gitlab.getProjects(100, firstId)
+      let projectData = projects.data[0]
 
       if (projectData.length == 0) {
         isProject = false
@@ -298,68 +298,60 @@ module.exports = function (app) {
     let isProject = true
     let firstId = 0
 
-    let runnerProjects = await gitlab.getProjectsFromRunners()
-    if(runnerProjects.error) {
-      // error response: to be updated
-      res.status(500).render(lang+'/500', { error: err })
-    } else {
-      let runnerProjectsData = runnerProjects.data
-      let runnerProjectsIds = [] 
-      for(let i = 0; i < runnerProjectsData.length; i++){
-        runnerProjectsIds.push(runnerProjectsData[i].id)
-      }
-
-      while (isProject == true) {
-        let pages = await gitlab.getPages(100, firstId)
-        let pagesData = pages.data
+    while (isProject == true) {
+      let projects = await gitlab.getProjects(100, firstId)
+      let pagesData = projects.data[1]
 
-        if (pagesData.length == 0) {
-          isProject = false
-        } else {
-          for(let i = 0; i < pagesData.length; i++){
-            //  ONLY IF THE PROJECT IS AVAILABLE IN THE RUNNER
-            if(runnerProjectsIds.indexOf(pagesData[i].id) > -1) {
-              // M4_LAB logo for all projects that do not have logo
-              if (pagesData[i].avatar_url == null) {
-                pagesData[i].avatar_url = "https://m4lab.hft-stuttgart.de/img/footer/M4_LAB_LOGO_Graustufen.png"
-              }
-              // for all projects that have no description
-              if (pagesData[i].description == "") {
-                pagesData[i].description = "- no description -"
-              }
-              // customize website name
-              if (pagesData[i].name == "Visualization") {
-                pagesData[i].web_url = "https://transfer.hft-stuttgart.de/pages/visualization"
-              }
-              else if (pagesData[i].name == "IN-Source") {
-                pagesData[i].web_url = "https://transfer.hft-stuttgart.de/pages/INsource"
-              }
-              else if (pagesData[i].name == "3DS_Visualization_Cesium") {
-                pagesData[i].web_url = "https://transfer.hft-stuttgart.de/pages/3ds_visualization_cesium"
-              }
-              else {
-                pagesData[i].web_url = "https://transfer.hft-stuttgart.de/pages/"+pagesData[i].name
-              }
-              // remove 'website' from tag list
-              let index = pagesData[i].tag_list.indexOf('website')
-              if (index > -1) {
-                pagesData[i].tag_list.splice(index, 1)
-              }
+      if (pagesData.length == 0) {
+        isProject = false
+      } else {
+        for(let i = 0; i < pagesData.length; i++){
+          let status = await gitlab.getLatestPipelineStatus(pagesData[i].id)
+          if (status) {
+            // M4_LAB logo for all projects that do not have logo
+            if (pagesData[i].avatar_url == null) {
+              pagesData[i].avatar_url = "https://m4lab.hft-stuttgart.de/img/footer/M4_LAB_LOGO_Graustufen.png"
+            }
+            // for all projects that have no description
+            if (pagesData[i].description == "") {
+              pagesData[i].description = "- no description -"
+            }
+            // customized website name
+            if (pagesData[i].name == "Visualization") {
+              //todo: update URL - user? group?
+              pagesData[i].web_url = "https://transfer.hft-stuttgart.de/pages/visualization"
+            }
+            else if (pagesData[i].name == "IN-Source") {
+              //todo: update URL
+              pagesData[i].web_url = "https://transfer.hft-stuttgart.de/pages/INsource"
+            }
+            else if (pagesData[i].name == "3DS_Visualization_Cesium") {
+              //todo: update URL
+              pagesData[i].web_url = "https://transfer.hft-stuttgart.de/pages/3ds_visualization_cesium"
+            }
+            else {
+              //todo: update URL
+              pagesData[i].web_url = "https://transfer.hft-stuttgart.de/pages/"+pagesData[i].name
+            }
+            // remove 'website' from tag list
+            let index = pagesData[i].tag_list.indexOf('website')
+            if (index > -1) {
+              pagesData[i].tag_list.splice(index, 1)
+            }
 
-              // fill in pagesArr
-              let pages = {
-                logo: pagesData[i].avatar_url,
-                name: pagesData[i].name,
-                weburl: pagesData[i].web_url,
-                desc: pagesData[i].description,
-                keywords: pagesData[i].tag_list
-              }
-              pagesArr.push(pages)
+            // fill in pagesArr
+            let pages = {
+              logo: pagesData[i].avatar_url,
+              name: pagesData[i].name,
+              weburl: pagesData[i].web_url,
+              desc: pagesData[i].description,
+              keywords: pagesData[i].tag_list
             }
+            pagesArr.push(pages)
           }
-          firstId = pagesData[pagesData.length-1].id
         }
-      }        
+        firstId = pagesData[pagesData.length-1].id
+      }
     }
 
     res.render(lang+'/project/pagesList', {
-- 
GitLab


From 06c2856a39588eae3ceeed33f18e03b7bef8819a Mon Sep 17 00:00:00 2001
From: Varun Srivastava <92srva1mst@hft-stuttgart.de>
Date: Thu, 1 Apr 2021 01:32:02 +0200
Subject: [PATCH 13/13] styling changes

---
 views/DE/project/mailinglists.pug    | 52 ++++++++++++++--------------
 views/DE/project/pagesList.pug       |  6 ++--
 views/DE/project/project.html        |  8 ++---
 views/DE/project/projectList.pug     |  6 ++--
 views/DE/project/projectOverview.pug |  8 ++---
 views/EN/project/mailinglists.pug    |  2 +-
 6 files changed, 41 insertions(+), 41 deletions(-)

diff --git a/views/DE/project/mailinglists.pug b/views/DE/project/mailinglists.pug
index bf3c747..cfffc9a 100644
--- a/views/DE/project/mailinglists.pug
+++ b/views/DE/project/mailinglists.pug
@@ -11,14 +11,14 @@ html(lang="de")
   body
     div(class="container")
         div(class="row")
-            div(class="col-md-12" style="margin-bottom: 40px;")
+            div(class="col-md-12 margin_bottom_40")
                 img(class="mx-auto" src="/img/Mailinglisten.jpg" width="100%")
     div(class="container")
         div(class="row")
-            div(class="col-md-12" style="margin-bottom: 30px;")
+            div(class="col-md-12 margin_bottom_30")
                 h4(class="text-center") Durch Mailinglisten können Sie interessierten Personen<br/> <strong>regelmäßig Informationen</strong> zu Ihrem Projekt oder Thema zukommen lassen.<br/> Ebenso können Sie über ein Abonnement in einer Mailingliste Mitglied des Verteilers<br/>werden und so <strong>im Austausch</strong> bleiben. <br/>
-            div(class="col-md-12" style="margin-bottom: 30px;")
-                h2(class="text-center" style="color: #708090;") <strong>Aktive Mailinglisten</strong>
+            div(class="col-md-12 margin_bottom_30")
+                h2(class="text-center color_708090") <strong>Aktive Mailinglisten</strong>
                 div(class="table-responsive table-borderless")
                     table(class="table table-striped table-bordered table-hover")
                         thead()
@@ -35,40 +35,40 @@ html(lang="de")
                                         td <a href="#{item.src}">#{item.src}</a>
                                         td <a href='projectoverview?projectID=#{item.id}'>#{item.project_title}</a>
                                         td #{item.keywords}
-    div(id="aboText" style="background-color: #dadada;margin-top: 40px;")
+    div(id="aboText" class="mailingList_aboText")
         div(class="container")
-            div(class="row" style="margin-bottom: 0;padding-top: 20px;padding-bottom: 20px;")
-                div(class="col-lg-12" style="background-color: #ffffff;")
-                    h2(class="text-center" style="color: #708090;margin-top: 15px;") <strong> Mailingliste abonnieren </strong>
-                div(class="col-md-4 col-lg-6" style="background-color: #ffffff;")
+            div(class="row m_bottom_0 p_top_20 p_bottom_20")
+                div(class="col-lg-12 background_ffffff")
+                    h2(class="text-center color_708090 m_top_15") <strong> Mailingliste abonnieren </strong>
+                div(class="col-md-4 col-lg-6 background_ffffff")
                     p() Das Deutsche Forschungsnetz (DFN) bietet Mailinglisten für Wissenschaft und Forschung an. Mailinglisten sind E-Mail-Verteilerlisten, d.h. Personen, die sich für Ihr Forschungsthema interessieren, können sich über das DFN registrieren und erhalten im Anschluss daran regelmäßig die über die Mailinglisten geteilten Informationen.
                     p() Sie als Verteiler senden die zu versendende Mail folglich nur noch an die festgelegte Mailinglistenadresse und das Programm leitet die Nachricht an alle registrierten Personen weiter.
-                div(class="col-md-4 col-lg-6 justify-content-between flex-wrap" style="background-color: #ffffff;")
-                    div(class="justify-content-between order-2" style="background-color: rgba(255,255,255,0);")
+                div(class="col-md-4 col-lg-6 justify-content-between flex-wrap background_ffffff")
+                    div(class="justify-content-between order-2 background_ffffff")
                         p(class="text-left d-flex d-md-flex flex-row flex-grow-1 flex-shrink-1 flex-fill justify-content-between align-items-start align-content-start align-self-start flex-wrap order-1 justify-content-md-center align-items-md-start justify-content-lg-start") Oben finden Sie eine Übersicht über die aktiven Mailinglisten. Wenn Sie sich in eine Mailingliste eintragen wollen, dann klicken Sie auf den entsprechend hinterlegten Link.
                         p() Es öffnet sich daraufhin die Hauptseite der Liste. Nach der Auswahl des Buttons "Abonnieren", können Sie Ihre Mailadresse hinterlegen und sich in die Liste eintragen.
-                    a(class="btn btn-primary text-center d-inline-flex d-lg-flex flex-column flex-grow-1 flex-shrink-1 flex-fill justify-content-between align-items-baseline align-content-center align-self-baseline flex-wrap order-3 justify-content-md-center align-items-md-end align-items-lg-center justify-content-xl-center mx-auto" role="button" style="background-color: #E0001B; margin-top:10px; margin-bottom:10px;" href="/downloads/Handout_Mailinglisten_Abonnieren.pdf") <strong>Erste Schritte (Anleitung als PDF)</strong>
-                    a(class="btn btn-primary text-center d-inline-flex d-lg-flex flex-column flex-grow-1 flex-shrink-1 flex-fill justify-content-between align-items-baseline align-content-center align-self-baseline flex-wrap mb-auto justify-content-md-center align-items-md-end align-items-lg-center justify-content-xl-center mx-auto" role="button" style="background-color: #E0001B;" href="https://www.listserv.dfn.de/sympa/help") <strong>Weitergehende Dokumentation bei DFN (externer Link)</strong>
+                    a(class="btn btn-primary text-center d-inline-flex d-lg-flex flex-column flex-grow-1 flex-shrink-1 flex-fill justify-content-between align-items-baseline align-content-center align-self-baseline flex-wrap order-3 justify-content-md-center align-items-md-end align-items-lg-center justify-content-xl-center mx-auto background_e0001b m_top_10" role="button" href="/downloads/Handout_Mailinglisten_Abonnieren.pdf") <strong>Erste Schritte (Anleitung als PDF)</strong>
+                    a(class="btn btn-primary text-center d-inline-flex d-lg-flex flex-column flex-grow-1 flex-shrink-1 flex-fill justify-content-between align-items-baseline align-content-center align-self-baseline flex-wrap mb-auto justify-content-md-center align-items-md-end align-items-lg-center justify-content-xl-center mx-auto background_e0001b m_top_10" role="button" href="https://www.listserv.dfn.de/sympa/help") <strong>Weitergehende Dokumentation bei DFN (externer Link)</strong>
 
-    div(id="newListText" style="background-color: #dadada;margin-top: 0px;")
+    div(id="newListText" class="mailingList_text")
         div(class="container")
-            div(class="row" style="margin-bottom: 0;padding-top: 20px;padding-bottom: 20px;")
-                div(class="col-lg-12" style="background-color: #ffffff;")
-                    h2(class="text-center" style="color: #708090;margin-top: 15px;") <strong>Neue Mailingliste erstellen</strong>
-                div(class="col-md-4 col-lg-6" style="background-color: #ffffff;")
+            div(class="row m_bottom_0 p_top_20 p_bottom_20")
+                div(class="col-lg-12 background_ffffff")
+                    h2(class="text-center color_708090 m_top_15") <strong>Neue Mailingliste erstellen</strong>
+                div(class="col-md-4 col-lg-6 background_ffffff")
                     p() Über das Transferportal können Sie selbst eine Liste zu Ihrem Projekt anlegen, um mit Ihren Partnern in Verbindung zu bleiben.
                     p() Folgen Sie hierzu der Anleitung des DFN.
 
-                div(class="col-md-4 col-lg-6 justify-content-between flex-wrap" style="background-color: #ffffff;")
-                    a(class="btn btn-primary text-center d-inline-flex d-lg-flex flex-column flex-grow-1 flex-shrink-1 flex-fill justify-content-between align-items-baseline align-content-center align-self-baseline flex-wrap order-3 justify-content-md-center align-items-md-end align-items-lg-center justify-content-xl-center mx-auto" role="button" style="background-color: #E0001B; margin-top:10px; margin-top:10px;" href="/downloads/Handout_Mailinglisten_Erstellen.pdf") <strong>Erste Schritte (Anleitung als PDF)</strong>
-                    a(class="btn btn-primary text-center d-inline-flex d-lg-flex flex-column flex-grow-1 flex-shrink-1 flex-fill justify-content-between align-items-baseline align-content-center align-self-baseline flex-wrap order-3 justify-content-md-center align-items-md-end align-items-lg-center justify-content-xl-center mx-auto" role="button" style="background-color: #E0001B; margin-top:10px; margin-top:10px;" href="https://www.listserv.dfn.de/sympa/help/admin") <strong>Gesamtes Tutorial bei DFN (externer Link)</strong>
+                div(class="col-md-4 col-lg-6 justify-content-between flex-wrap background_ffffff")
+                    a(class="btn btn-primary text-center d-inline-flex d-lg-flex flex-column flex-grow-1 flex-shrink-1 flex-fill justify-content-between align-items-baseline align-content-center align-self-baseline flex-wrap order-3 justify-content-md-center align-items-md-end align-items-lg-center justify-content-xl-center mx-auto background_e0001b m_top_10" role="button" href="/downloads/Handout_Mailinglisten_Erstellen.pdf") <strong>Erste Schritte (Anleitung als PDF)</strong>
+                    a(class="btn btn-primary text-center d-inline-flex d-lg-flex flex-column flex-grow-1 flex-shrink-1 flex-fill justify-content-between align-items-baseline align-content-center align-self-baseline flex-wrap order-3 justify-content-md-center align-items-md-end align-items-lg-center justify-content-xl-center mx-auto background_e0001b m_top_10" role="button" href="https://www.listserv.dfn.de/sympa/help/admin") <strong>Gesamtes Tutorial bei DFN (externer Link)</strong>
 
-    div(id="addListText" style="background-color: #dadada;margin-top: 0px;")
+    div(id="addListText" class="mailingList_text")
         div(class="container")
-            div(class="row" style="margin-bottom: 0;padding-top: 20px;padding-bottom: 20px;")
-                div(class="col-lg-12" style="background-color: #ffffff;")
-                    h2(class="text-center" style="color: #708090;margin-top: 15px;") <strong>Neue Mailingliste eintragen</strong>
-                div(class="col-xl" style="background-color: #ffffff;")
+            div(class="row m_bottom_0 p_top_20 p_bottom_20")
+                div(class="col-lg-12 background_ffffff")
+                    h2(class="text-center color_708090 m_top_15") <strong>Neue Mailingliste eintragen</strong>
+                div(class="col-xl background_ffffff")
                     p() Um Ihre beim DFN angelegte Mailingliste hier aufzunehmen, schicken Sie uns bitte eine Email an <a href="mailto:support-transfer@hft-stuttgart.de">support-transfer@hft-stuttgart.de</a>
     // jQuery
     script(src="https://code.jquery.com/jquery-3.3.1.min.js")
diff --git a/views/DE/project/pagesList.pug b/views/DE/project/pagesList.pug
index b690a89..29ccdf7 100644
--- a/views/DE/project/pagesList.pug
+++ b/views/DE/project/pagesList.pug
@@ -29,7 +29,7 @@ html(lang="de")
   body
     div(class="container")
             div(class="row")
-                div(class="col-md-12" style="margin-bottom: 40px;")
+                div(class="col-md-12 margin_bottom_40")
                     img(class="mx-auto" src="/img/Projektinformationen.png" width="100%")
     div(class="container")
         div(class="pt-4 pb-4 form-row")
@@ -46,7 +46,7 @@ html(lang="de")
             | <div class="row">
             for item in pages
                 div(class="card-deck py-4 col-sm")
-                    div(class="card", style="width: 18rem;")
+                    div(class="card width_18")
                         div(class="title-container")
                             h5(class="card-title-bottom-left") #{item.name}
                             img(class="card-img-top", src=item.logo)
@@ -59,7 +59,7 @@ html(lang="de")
                             div(class="row")
                                 div(class="col-9")
                                     p(class="card-text") #{item.desc}
-                                a(href=item.weburl, style="text-decoration: none;", target="_blank")
+                                a(href=item.weburl, class="no_text_decoration", target="_blank")
                                     div(class="col-3")
                                         svg(class="bi bi-chevron-right", width="32", height="32", viewBox="0 0 20 20", fill="black", xmlns="http://www.w3.org/2000/svg")
                                             | <path fill-rule="evenodd" d="M6.646 3.646a.5.5 0 01.708 0l6 6a.5.5 0 010 .708l-6 6a.5.5 0 01-.708-.708L12.293 10 6.646 4.354a.5.5 0 010-.708z"></path>
diff --git a/views/DE/project/project.html b/views/DE/project/project.html
index 52026e8..d2fa063 100644
--- a/views/DE/project/project.html
+++ b/views/DE/project/project.html
@@ -1,7 +1,7 @@
 <div>
     <div class="container">
         <div class="row">
-            <div class="col-md-12" style="margin-bottom: 40px;"><img class="mx-auto" src="/img/Projekte.png"
+            <div class="col-md-12 margin_bottom_40"><img class="mx-auto" src="/img/Projekte.png"
                     width="100%"></div>
         </div>
     </div>
@@ -9,7 +9,7 @@
 <div>
     <div class="container">
         <div class="row">
-            <div class="col-md-12" style="margin-bottom: 30px;">
+            <div class="col-md-12 margin_bottom_30">
                 <h4 class="text-center">Diese Seite bietet den Einstieg zu den Inhalten der unterschiedlichen Projekte,
                     die über das Portal zur Verfügung gestellt werden.</h4>
             </div>
@@ -20,7 +20,7 @@
     <div class="container">
         <div class="row">
             <div class="col-lg-1"></div>
-            <div class="col-md-6 col-lg-4" style="padding-right: 5px;padding-left: 5px;">
+            <div class="col-md-6 col-lg-4 p_left_5 p_right_5">
                 <img class="d-flex d-lg-flex justify-content-center align-items-center align-content-center align-self-center mx-auto"
                     src="/img/Icon_Haken.png" height="150" />
                 <br />
@@ -34,7 +34,7 @@
                 </p>
             </div>
             <div class="col-lg-2"></div>
-            <div class="col-md-6 col-lg-4" style="padding-right: 5px;padding-left: 5px;">
+            <div class="col-md-6 col-lg-4 p_left_5 p_right_5">
                 <img src="/img/Icon_Sandclock.png"
                     class="d-flex d-lg-flex justify-content-center align-items-center align-content-center align-self-center mx-auto"
                     height="150px" />
diff --git a/views/DE/project/projectList.pug b/views/DE/project/projectList.pug
index c3af451..61aa995 100644
--- a/views/DE/project/projectList.pug
+++ b/views/DE/project/projectList.pug
@@ -29,7 +29,7 @@ html(lang="de")
   body
     div(class="container")
             div(class="row")
-                div(class="col-md-12" style="margin-bottom: 40px;")
+                div(class="col-md-12 margin_bottom_40")
                     img(class="mx-auto" src="/img/ProjektcodeDaten.png" width="100%")
     div(class="container")
         div(class="pt-4 pb-4 form-row")
@@ -46,7 +46,7 @@ html(lang="de")
             | <div class="row">
             for item in project
                 div(class="card-deck py-4 col-sm")
-                    div(class="card", style="width: 18rem;")
+                    div(class="card width_18")
                         div(class="title-container")
                             h5(class="card-title-bottom-left") #{item.name}
                             img(class="card-img-top", src=item.logo)
@@ -59,7 +59,7 @@ html(lang="de")
                             div(class="row")
                                 div(class="col-9")
                                     p(class="card-text") #{item.desc}
-                                a(href=item.weburl, style="text-decoration: none;", target="_blank")
+                                a(href=item.weburl, class="no_text_decoration", target="_blank")
                                     div(class="col-3")
                                         svg(class="bi bi-chevron-right", width="32", height="32", viewBox="0 0 20 20", fill="black", xmlns="http://www.w3.org/2000/svg")
                                             | <path fill-rule="evenodd" d="M6.646 3.646a.5.5 0 01.708 0l6 6a.5.5 0 010 .708l-6 6a.5.5 0 01-.708-.708L12.293 10 6.646 4.354a.5.5 0 010-.708z"></path>
diff --git a/views/DE/project/projectOverview.pug b/views/DE/project/projectOverview.pug
index c180b3e..8ad852e 100644
--- a/views/DE/project/projectOverview.pug
+++ b/views/DE/project/projectOverview.pug
@@ -14,9 +14,9 @@ html(lang="de")
             div(class="row")
                 div(class="col-sm-8 pt-3")
                     h1 #{project.title}
-                    div(style="float:right; margin-left:30px; margin-bottom:0px; width:50%;")
+                    div(class="project_overview")
                         img(src=project.src, width="100%")
-                        p(style="text-align:right") #{project.caption}
+                        p(class="text-center mr-5") #{project.caption}
 
                     h2(class="pt-4") Projektüberblick
                     p !{project.overview}
@@ -29,7 +29,7 @@ html(lang="de")
                     p !{project.approach}
                     h2(class="pt-4") Ergebnis und Nutzung
                     p !{project.result}
-                div(class="col-sm-4 pt-3" style="background-color: #f1f1f1")
+                div(class="col-sm-4 pt-3 background_f1f1f1")
                     for image in projectImgs
                         if image.pos == '2' || image.pos == '3'
                             div(class="projectimg")
@@ -115,7 +115,7 @@ html(lang="de")
                             span !{project.further_details}
 
                     if project.pname == 'M4LAB'
-                        div(class="Downloads" style="height:200px;")
+                        div(class="Downloads")
                             h5 Downloads
 
                         div(class="Projektlogos")
diff --git a/views/EN/project/mailinglists.pug b/views/EN/project/mailinglists.pug
index 75bc8de..3919e19 100644
--- a/views/EN/project/mailinglists.pug
+++ b/views/EN/project/mailinglists.pug
@@ -30,7 +30,7 @@ html(lang="en")
     <hr />
     div()
         h5(align="left") Aktive Mailinglisten
-        div(class="flex-container" style="align-items:flex-start")
+        div(class="flex-container mailinglist_activetable")
             div(class="table")
                 table(border="0" id="listtable" class="table table-striped")
                     thead
-- 
GitLab