account.js 20.4 KB
Newer Older
1
2
const fs = require('fs')
const SamlStrategy = require('passport-saml').Strategy
Rosanny Sihombing's avatar
Rosanny Sihombing committed
3
4
5
const dbconn = require('../config/dbconn')
const methods = require('../functions/methods')
const gitlab = require('../functions/gitlab')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
6
const constants = require('../config/const')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
7
// pwd encryption
8
9
10
const bcrypt = require('bcryptjs');
const saltRounds = 10;
const salt = 64; // salt length
Rosanny Sihombing's avatar
Rosanny Sihombing committed
11
// forgot pwd
12
13
const async = require('async')
const crypto = require('crypto')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
14
const mailer = require('../config/mailer')
15
const logoDir = 'public/upload/'
Rosanny Sihombing's avatar
Rosanny Sihombing committed
16
const defaultLogo = 'public/default/logo.png'
17
const tpGitlabURL = 'https://transfer.hft-stuttgart.de/gitlab/'
Rosanny Sihombing's avatar
Rosanny Sihombing committed
18
const tpGitlabPagesURL = 'https://transfer.hft-stuttgart.de/pages/'
Rosanny Sihombing's avatar
Rosanny Sihombing committed
19

20
21
22
const portalUser = require('../classes/user')
const projectInformation = require('../classes/website')
const projectRepo = require('../classes/repo')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
23

Rosanny Sihombing's avatar
Rosanny Sihombing committed
24
module.exports = function (app, config, passport, lang) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

  // =========== PASSPORT =======
  passport.serializeUser(function (user, done) {
    done(null, user);
  });

  passport.deserializeUser(function (user, done) {
    done(null, user);
  });

  var samlStrategy = new SamlStrategy({
      // URL that goes from the Identity Provider -> Service Provider
      callbackUrl: config.passport.saml.path,
      // Base address to call logout requests
      logoutUrl: config.passport.saml.logoutUrl,
      
      entryPoint: config.passport.saml.entryPoint,
      issuer: config.passport.saml.issuer,
      identifierFormat: null,
      
      // Service Provider private key
      decryptionPvk: fs.readFileSync(__dirname + '/cert/key.pem', 'utf8'),
      // Service Provider Certificate
      privateCert: fs.readFileSync(__dirname + '/cert/key.pem', 'utf8'),
      // Identity Provider's public key
      cert: fs.readFileSync(__dirname + '/cert/cert_idp.pem', 'utf8'),
      
      validateInResponseTo: false,
      disableRequestedAuthnContext: true
54
55
56
57
58
59
60
61
  },
  function (profile, done) {
    return done(null, {
      id: profile.nameID,
      idFormat: profile.nameIDFormat,
      email: profile.email,
      firstName: profile.givenName,
      lastName: profile.sn
Rosanny Sihombing's avatar
Rosanny Sihombing committed
62
    });
63
  });
Rosanny Sihombing's avatar
Rosanny Sihombing committed
64
65
  
  passport.use(samlStrategy);
66
67
68
69
70

  // ============= SAML ==============
  app.post(config.passport.saml.path,
    passport.authenticate(config.passport.strategy,
      {
71
        failureRedirect: '/account/',
72
73
74
        failureFlash: true
      }),
    function (req, res) {
75
      res.redirect('/account/');
76
77
78
79
    }
  );

  // to generate Service Provider's XML metadata
80
  app.get('/saml/metadata',
81
82
83
84
85
86
    function(req, res) {
      res.type('application/xml');
      var spMetadata = samlStrategy.generateServiceProviderMetadata(fs.readFileSync(__dirname + '/cert/cert.pem', 'utf8'));
      res.status(200).send(spMetadata);
    }
  );
Wolfgang Knopki's avatar
Wolfgang Knopki committed
87
88

  // ======== APP ROUTES - ACCOUNT ====================
Rosanny Sihombing's avatar
DE    
Rosanny Sihombing committed
89

90
91
  async function getLoggedInUserData(email) {
    let user = await methods.getUserByEmail(email)
92
93
94
95
96
97
98
99
100
101
102
103
104
    if (!user) {
      console.log('no user found')
      return null
    } else {
      let loggedInUser = new portalUser(
        user.id, email, user.salutation, user.title, user.firstname, user.lastname, user.industry, user.organisation, user.speciality, user.m4lab_idp, null, user.verificationStatus
      )
      
      let userGitlabId = await methods.getGitlabId(loggedInUser.id)
      if (userGitlabId) {
        loggedInUser.setGitlabUserId(userGitlabId)
      }
      return loggedInUser
Rosanny Sihombing's avatar
Rosanny Sihombing committed
105
    }
106
107
108
  }

  app.get('/', async function (req, res) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
109
110
111
    if ( !req.isAuthenticated() ) {
      res.redirect('/login')
    } else {
112
113
114
115
116
      let loggedInUser = await getLoggedInUserData(req.user.email)
      
      res.render(lang+'/account/home', {
        user: loggedInUser
      });
117
    }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
118
119
  });

Rosanny Sihombing's avatar
Rosanny Sihombing committed
120
  app.get('/login',
Rosanny Sihombing's avatar
Rosanny Sihombing committed
121
122
123
124
125
    passport.authenticate(config.passport.strategy, {
      successRedirect: '/',
      failureRedirect: '/login'
    })
  )
Rosanny Sihombing's avatar
Rosanny Sihombing committed
126

127
128
  app.get('/logout', function (req, res) {
    if (req.user == null) {
129
      return res.redirect('/');
Rosanny Sihombing's avatar
Rosanny Sihombing committed
130
    }
Wolfgang Knopki's avatar
Wolfgang Knopki committed
131

132
133
134
135
    req.user.nameID = req.user.id;
    req.user.nameIDFormat = req.user.idFormat;
    return samlStrategy.logout(req, function(err, uri) {
      req.logout();
136

137
138
139
140
141
142
143
      if ( req.session ) {
        req.session.destroy((err) => {
          if(err) {
              return console.log(err);
          }
        });
      }
144

145
146
147
      return res.redirect(uri);
    });
  });
Rosanny Sihombing's avatar
Rosanny Sihombing committed
148

149
150
  app.get('/profile', async function (req, res) {
    if ( !req.isAuthenticated() ) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
151
      res.redirect('/login')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
152
    } else {
153
      let loggedInUser = await getLoggedInUserData(req.user.email)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
154
155
156
157
158
159
160
      if(loggedInUser.getVerificationStatus() != 1) {
        res.redirect('/account/')
      } else {
        res.render(lang+'/account/profile', {
          user: loggedInUser
        })
      }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
161
    }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
162
  })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
163

Rosanny Sihombing's avatar
Rosanny Sihombing committed
164
  app.get('/services', async function(req, res){
165
    if( !req.isAuthenticated() ) {
166
167
      res.redirect('/login')
    } else {
168
      let loggedInUser = await getLoggedInUserData(req.user.email)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
169
170
      if(loggedInUser.getVerificationStatus() != 1) { // unverified users
        res.redirect('/account/')
171
      } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
172
173
        let gitlabReposArr = []
        let gitlabPagesArr = []
Rosanny Sihombing's avatar
Rosanny Sihombing committed
174

Rosanny Sihombing's avatar
Rosanny Sihombing committed
175
        if(loggedInUser.getGitlabUserId()) { // for users who have activated their gitlab account
Rosanny Sihombing's avatar
Rosanny Sihombing committed
176
          let userProjects = await gitlab.getUserProjects(loggedInUser.getGitlabUserId())
Rosanny Sihombing's avatar
Rosanny Sihombing committed
177
178
179
180
          if (!userProjects) {
            console.error("something went wrong")
            res.status(500).render(lang+'/500', { error: "something went wrong" })
          }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
181
182
183
184
185
186
187
          
          for (project in userProjects) {
            if (userProjects[project].tag_list.includes('website')) {
              let page = {
                projectInformation: new projectInformation(loggedInUser.getGitlabUserId(), userProjects[project].id, userProjects[project].name,
                  userProjects[project].description, userProjects[project].avatar_url, userProjects[project].path_with_namespace),
                pipelineStatus: await gitlab.getProjectPipelineLatestStatus(userProjects[project].id)
188
              }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
189
190
191
192
193
194
195
196
197
198
199
200
              gitlabPagesArr.push(page)
            } else {
              let repo = new projectRepo(loggedInUser.getGitlabUserId(), userProjects[project].id, userProjects[project].name,
                userProjects[project].description, userProjects[project].avatar_url, userProjects[project].path_with_namespace)
              gitlabReposArr.push(repo)
            }
          }

          res.render(lang+'/account/services', {
            user: loggedInUser,
            gitlabRepos: gitlabReposArr,
            gitlabPages: gitlabPagesArr
Rosanny Sihombing's avatar
Rosanny Sihombing committed
201
          })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
202
        } else { // for users who have not activated their gitlab account yet
Rosanny Sihombing's avatar
Rosanny Sihombing committed
203
          let gitlabUser = await gitlab.getUserByEmail(loggedInUser.getEmail())
Rosanny Sihombing's avatar
Rosanny Sihombing committed
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
          if (!gitlabUser) {
            res.render(lang+'/account/services', {
              user: loggedInUser,
              gitlabRepos: null,
              gitlabPages: null
            })
          } else {
            let gitlabActivationData = {
              user_id: loggedInUser.getId(),
              gitlab_userId: gitlabUser.id}
            // RS: update to await?
            methods.addGitlabUser(gitlabActivationData, function(err){
              if(err) {
                res.status(500).render(lang+'/500', { error: err })
              } else {
                res.redirect('/account/services')
              }
            })
          }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
223
        }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
224
      }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
225
    }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
226
  })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
227

228
229
  app.get('/security', async function (req, res) {
    if ( !req.isAuthenticated() ) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
230
      res.redirect('/login')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
231
    } else {
232
      let loggedInUser = await getLoggedInUserData(req.user.email)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
233
234
235
236
237
238
239
      if(loggedInUser.getVerificationStatus() == 1 && loggedInUser.getIdpStatus() == 1) {
        res.render(lang+'/account/security', {
          user: loggedInUser
        })
      } else {
        res.redirect('/account/')
      }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
240
    }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
241
  })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
242

243
  app.post('/updateProfile', async function (req, res) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
244
    var userData = {
Rosanny Sihombing's avatar
DE    
Rosanny Sihombing committed
245
      salutation: req.body.inputSalutation,
Rosanny Sihombing's avatar
Rosanny Sihombing committed
246
247
248
249
250
251
252
253
      title: req.body.inputTitle,
      firstname: req.body.inputFirstname,
      lastname: req.body.inputLastname,
      email: req.body.inputEmail,
      organisation: req.body.inputOrganisation,
      industry: req.body.inputIndustry,
      speciality: req.body.inputSpeciality,
    }
254

255
    if ( !req.isAuthenticated() ) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
256
257
      res.redirect('/login')
    } else {
258
      let loggedInUser = await getLoggedInUserData(req.user.email)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
259
      if (userData.email) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
260
        dbconn.user.query('UPDATE user SET ? WHERE email = "' +userData.email+'"', userData, function (err, rows, fields) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
261
            if (err) {
262
              res.flash('error', "Failed")
Rosanny Sihombing's avatar
Rosanny Sihombing committed
263
264
            }
            else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
265
266
              loggedInUser.updateProfile(userData.salutation, userData.title, userData.firstname, userData.lastname, userData.email,
                userData.organisation, userData.industry, userData.speciality)
267
              res.flash('success', 'Ihr Benutzerprofil wurde aktualisiert!')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
268
            }
Wolfgang Knopki's avatar
Wolfgang Knopki committed
269
            res.redirect('/account/profile');
Rosanny Sihombing's avatar
Rosanny Sihombing committed
270
271
272
273
        })
      }
    }
  });
274

275
276
  app.post('/changePwd', async function (req, res) {
    if( !req.isAuthenticated() ) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
277
278
      res.redirect('/login')
    } else {
279
280
      let loggedInUser = await getLoggedInUserData(req.user.email)

Rosanny Sihombing's avatar
Rosanny Sihombing committed
281
282
283
284
      var currPwd = req.body.inputCurrPwd
      var newPwd = req.body.inputNewPwd
      var retypePwd = req.body.inputConfirm

Rosanny Sihombing's avatar
Rosanny Sihombing committed
285
286
287
288
289
290
291
      // update - get userId from loggedInUser
      dbconn.user.query('SELECT password FROM credential WHERE user_id='+loggedInUser.getId(), function (err, rows, fields) {
        if (err) {
          console.error(err)
          res.status(500).render(lang+'/500', { error: err })
        }
        var userPwd = rows[0].password
292

Rosanny Sihombing's avatar
Rosanny Sihombing committed
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
        // check if the password is correct
        bcrypt.compare(currPwd, userPwd, function(err, isMatch) {
          if (err) {
            console.error(err)
            res.status(500).render(lang+'/500', { error: err })
          } else if (!isMatch) {
            res.flash('error', "Das Passwort ist leider falsch. Bitte überprüfen Sie Ihre Eingabe.")
            res.redirect('/account/security')
          } else {
            if ( newPwd != retypePwd ) {
              res.flash('error', 'Passwörter stimmen nicht überein. Bitte stellen Sie sicher, dass Sie das Passwort beide Male genau gleich eingeben.')
              res.redirect('/account/security')
            } else {
              // update password
              bcrypt.genSalt(saltRounds, function(err, salt) {
                bcrypt.hash(newPwd, salt, function(err, hash) {
                  var credentialData = {
                    password: hash,
                    user_id: userId
                  }
                  methods.updateCredential(credentialData, function(err){
                    if (err) {
                      res.flash('error', "Datenbankfehler: Passwort kann nicht geändert werden.")
                      throw err
                    } else {
                      res.flash('success', "Passwort aktualisiert!")
                      mailer.options.to = req.user.email
Rosanny Sihombing's avatar
Rosanny Sihombing committed
320
321
                      mailer.options.subject = constants.updatePasswordMailSubject
                      mailer.options.html = constants.updatePasswordMailContent+'<div>'+constants.mailSignature+'</div>'
Rosanny Sihombing's avatar
Rosanny Sihombing committed
322
323
324
325
326
327
328
329
330
331
                      mailer.transport.sendMail(mailer.options, function(err) {
                        if (err) { console.log(err) }
                      });
                    }
                    res.redirect('/account/security')
                  })
                });
              });
            }
          }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
332
        })
333
      })
334
    }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
335
  });
Rosanny Sihombing's avatar
Rosanny Sihombing committed
336
  
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
  app.get('/resendVerificationEmail', async function(req, res){
    if (!req.isAuthenticated) {
      res.redirect('/login')
    } else {
      let loggedInUser = await getLoggedInUserData(req.user.email)
      if (!loggedInUser) {
        res.redirect('/login')
      } else {
        let token = await methods.getVerificationTokenByUserId(loggedInUser.id)
        if (!token) {
          res.send(false)
        } else {
          // send email
          var emailSubject = "Bitte bestätigen Sie Ihr M4_LAB Benutzerkonto"
          var emailContent = '<div>Lieber Nutzer,<br/><br/>' +
            '<p>vielen Dank für Ihre Anmeldung am Transferportal der HFT Stuttgart. <br/>' +
            'Um Ihre Anmeldung zu bestätigen, klicken Sie bitte diesen Link: ' + config.app.host + '/verifyAccount?token=' + token +
            '<br/><br/>' +
            'Ohne Bestätigung Ihres Kontos müssen wir Ihr Konto leider nach 7 Tagen löschen.</p><br/>' + constants.mailSignature +
            '</div>';
          mailer.options.to = loggedInUser.email;
          mailer.options.subject = emailSubject;
          mailer.options.html = emailContent;
          mailer.transport.sendMail(mailer.options, function(err) {
            if (err) {
              console.log('cannot send email')
              throw err
Rosanny Sihombing's avatar
Rosanny Sihombing committed
364
365
366
            }
          })
          res.send(true)
367
        }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
368
      }
369
    }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
370
  })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
371

Rosanny Sihombing's avatar
Rosanny Sihombing committed
372
  // ============= NEW GITLAB PAGES ===========================
373
  
Rosanny Sihombing's avatar
Rosanny Sihombing committed
374
  app.get('/newInformation', async function(req, res){
375
    if ( !req.isAuthenticated() ) {
376
377
      res.redirect('/login')
    } else {
378
      let loggedInUser = await getLoggedInUserData(req.user.email)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
379
380
      let gitlabUser = await gitlab.getUserByEmail(loggedInUser.getEmail())
      if (!gitlabUser) { // no user found
Rosanny Sihombing's avatar
Rosanny Sihombing committed
381
        res.redirect('/account/services')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
382
383
384
385
386
387
      } else {
        res.render(lang+'/account/newInformation', {
          user: loggedInUser,
          gitlabUsername: gitlabUser.username
        })
      }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
388
    }
389
  })
390
391
  app.post('/newInformation', async function(req, res) {
    if( !req.isAuthenticated() ) {
392
393
      res.redirect('/login')
    } else {
394
395
      let loggedInUser = await getLoggedInUserData(req.user.email)

396
      if (!req.body.name && !req.body.description) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
397
        res.flash('error', 'Bitte geben Sie die benötigten Daten ein')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
398
        res.redirect('/account/newInformation')
399
400
401
      } else {
        let projectName = req.body.name.toLowerCase().replace(/\s/g, '-')
        let projectDesc = req.body.description
Rosanny Sihombing's avatar
Rosanny Sihombing committed
402
403
        let projectTemplate = req.body.template
        let newInformation = new projectInformation(loggedInUser.getGitlabUserId(), null, projectName, projectDesc, null, null)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
404
405
406
407
408
409
410
411
412
        let newLogoFile = defaultLogo
          
        if (req.files) { newLogoFile = req.files.logo }

        async.waterfall([
          function(callback){ // upload logo
            if (!req.files) {
              callback(null, newLogoFile)
            } else {
413
414
415
416
              newLogoFile.mv(logoDir + newLogoFile.name, function(err) {
                newLogoFile = logoDir+newLogoFile.name
                callback(err, newLogoFile)
              })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
417
418
419
420
421
422
423
            }
          },
          async function(newLogoFile){ // create a new GitLab Page
            let newPages = await gitlab.createNewPages(newInformation, newLogoFile, projectTemplate)
            if (newPages.error) {
              if(newPages.data.message.name == "has already been taken") {
                res.flash("error", "Der Projektname '"+newInformation.getName()+"' ist bereits vergeben, bitte wählen Sie einen anderen Namen.")
Rosanny Sihombing's avatar
Rosanny Sihombing committed
424
              } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
425
                res.flash("error", "Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut. ")
Rosanny Sihombing's avatar
Rosanny Sihombing committed
426
              }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
427
428
429
430
431
432
433
434
435
              res.redirect('/account/newInformation')
            } else {
              let newPagesData = newPages.data
        
              res.flash("success", "Ihre Webseite wurde erstellt, aber noch nicht veröffentlicht. Um Ihre Webseite endgültig zu veröffentlichen, "+
                "schließen Sie die Einrichtung gemäß unten stehender Anleitung ab.")
              /* res.flash("success", "Your website will be published AFTER you complete your website by following the provided guideline below."+
                "\r\n Your website URL: "+tpGitlabPagesURL+newPagesData.path_with_namespace+"/home/") */
              res.redirect('/account/updateInformation?id='+newPagesData.id)
436
            }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
437
438
439
440
441
          }
        ], function (err) {
          if(err) console.log(err)
          // remove logo
          if (req.files) {
442
443
444
            fs.unlink(newLogoFile, (err) => {
              if(err) console.log(err)
            })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
445
446
          }
        })
447
      }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
448
449
450
    }
  })

Rosanny Sihombing's avatar
Rosanny Sihombing committed
451
  app.get('/updateInformation', async function(req, res){
452
    if( !req.isAuthenticated() ) {
453
454
      res.redirect('/login')
    } else {
455
456
      let loggedInUser = await getLoggedInUserData(req.user.email)

457
458
459
      if(!req.query.id) {
        res.redirect('/account/services')
      } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
460
461
        let project = await gitlab.getProjectById(req.query.id)
        if (!project) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
462
463
464
465
          console.log(" ========= Error or no project found")
          res.redirect('/account/services')
        } else if (!project.owner) {
          console.log(" ========= Project cannot be accessed, since it does not have an owner")
Rosanny Sihombing's avatar
Rosanny Sihombing committed
466
467
          res.redirect('/account/services')
        } else if (project.owner.id != loggedInUser.getGitlabUserId()) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
468
          console.log(" ========= Access denied: Not your project")
Rosanny Sihombing's avatar
Rosanny Sihombing committed
469
470
471
472
473
474
475
476
477
478
          res.redirect('/account/services')
        } else {
          let curInformation = new projectInformation(loggedInUser.getGitlabUserId(), req.query.id, project.name, project.description,
            project.avatar_url, project.path_with_namespace)
          
          res.render(lang+'/account/updateInformation', {
            user: loggedInUser,
            information: curInformation
          })
        }
479
480
481
      }
    }
  })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
482
  // update a website
483
484
  app.post('/updateInformation', async function(req, res){
    if( !req.isAuthenticated() ) {
485
486
      res.redirect('/login')
    } else {
487
488
      let loggedInUser = await getLoggedInUserData(req.user.email)

489
      if (!req.body.name && !req.body.description) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
490
        res.flash('error', 'Bitte geben Sie die benötigten Daten ein')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
491
        res.redirect('/account/updateInformation')
492
      } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
493
494
        let projectName = req.body.name.toLowerCase().replace(/\s/g, '-')
        let projectDesc = req.body.description
Rosanny Sihombing's avatar
Rosanny Sihombing committed
495
        let updatedInformation = new projectInformation(loggedInUser.getGitlabUserId(), req.query.id, projectName, projectDesc, null, null)
496
        let newLogoFile
Rosanny Sihombing's avatar
Rosanny Sihombing committed
497

Rosanny Sihombing's avatar
Rosanny Sihombing committed
498
        async.waterfall([
499
500
501
502
503
504
505
506
507
508
          function(callback){ // upload logo
            if(!req.files) {
              callback(null, newLogoFile)
            } else {
              newLogoFile = req.files.logo
              newLogoFile.mv(logoDir + newLogoFile.name, function(err) {
                newLogoFile = logoDir + newLogoFile.name
                callback(err, newLogoFile)
              })
            }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
509
          },
Rosanny Sihombing's avatar
Rosanny Sihombing committed
510
511
512
          async function(newLogoFile, callback){ // update gitlab page
            let updatedPages = await gitlab.updateProject(updatedInformation, newLogoFile)
            let pagesData = updatedPages.data
513
            if (updatedPages.error) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
514
515
              if(pagesData.message.name == "has already been taken") {
                res.flash("error", "Der Projektname ist bereits vergeben, bitte wählen Sie einen anderen Namen.")
516
              } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
517
                res.flash("error", "Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut. ")
Rosanny Sihombing's avatar
Rosanny Sihombing committed
518
              }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
519
520
521
            } else {
              updatedInformation.setLogo(pagesData.avatar_url)
              updatedInformation.setPath(pagesData.path)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
522
              res.flash("success", "Ihre Website wurde aktualisiert")
Rosanny Sihombing's avatar
Rosanny Sihombing committed
523
524
            }
            res.redirect('/account/updateInformation?id='+updatedInformation.getId())
525
526
527
528
529
530
          }
        ], function (err) {
          if(err) console.log(err)
          if(newLogoFile){ // remove logo
            fs.unlink(newLogoFile, (err) => {
              if(err) console.log(err)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
531
532
            })
          }
533
        })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
534
535
      }
    }
536
537
  })

Rosanny Sihombing's avatar
Rosanny Sihombing committed
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
  app.delete('/deleteProject', async function(req, res){
    console.log("delete project")

    if( !req.isAuthenticated() ) {
      res.redirect('/login')
    } else {
      let loggedInUser = await getLoggedInUserData(req.user.email)
      let projectId = req.body.id

      if (projectId) {
        // check if the owner is valid
        let project = await gitlab.getProjectById(projectId)
        if (!project) {
          console.log(" ========= Error or no project found")
        } else if (!project.owner) {
          console.log(" ========= Project cannot be accessed, since it does not have an owner")
        } else if (project.owner.id != loggedInUser.getGitlabUserId()) {
          console.log(" ========= Access denied: Not your project")
        } else {
          // delete project
          let project = await gitlab.deleteProjectById(projectId)
          if (project.error) {
            res.flash("error", "Project cannot be deleted. Please try again.")
          }
        }
      }
      res.redirect('/account/services')
    }
  })
567
568

}