account.ts 21.8 KB
Newer Older
Rosanny Sihombing's avatar
Rosanny Sihombing committed
1
2
3
4
import fs from 'fs'
import async from 'async'
import bcrypt from 'bcryptjs'
import * as passportSaml from 'passport-saml'
Rosanny Sihombing's avatar
Rosanny Sihombing committed
5
import { dbConnection } from '../config/dbconn'
Rosanny Sihombing's avatar
Rosanny Sihombing committed
6
7
import { dbController } from '../controller/dbController'
import { gitlabController } from '../controller/gitlabController'
Rosanny Sihombing's avatar
Rosanny Sihombing committed
8
9
10
11
12
import { miscConst } from '../config/const'
import { mailer } from '../config/mailer'
import { User } from '../classes/user'
import { Website } from '../classes/website'
import { Repo } from '../classes/repo'
Rosanny Sihombing's avatar
Rosanny Sihombing committed
13
14

const SamlStrategy = passportSaml.Strategy
Rosanny Sihombing's avatar
Rosanny Sihombing committed
15
16
const saltRounds = 10
const salt = 64 // salt length
Rosanny Sihombing's avatar
Rosanny Sihombing committed
17
const logoDir = 'public/upload/'
Rosanny Sihombing's avatar
Rosanny Sihombing committed
18
const defaultLogo: any = 'public/default/logo.png'
Rosanny Sihombing's avatar
Rosanny Sihombing committed
19

Rosanny Sihombing's avatar
Rosanny Sihombing committed
20
module.exports = function (app: any, config: any, passport: any, lang: string) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
21
  // =========== PASSPORT =======
Rosanny Sihombing's avatar
Rosanny Sihombing committed
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
  passport.serializeUser(function (user: any, done: any) {
    done(null, user)
  })

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

  const 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: undefined,

    // Service Provider private key
    decryptionPvk: fs.readFileSync(__dirname + '/cert/key.pem', 'utf8'),
    // Service Provider Certificate
    privateKey: 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
Rosanny Sihombing's avatar
Rosanny Sihombing committed
49
  },
Rosanny Sihombing's avatar
Rosanny Sihombing committed
50
  function (profile: any, done: any) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
51
52
53
54
55
56
    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
57
58
59
60
    })
  })

  passport.use(samlStrategy)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
61
62
63
64
65
66
67
68

  // ============= SAML ==============
  app.post(config.passport.saml.path,
    passport.authenticate(config.passport.strategy,
      {
        failureRedirect: '/account/',
        failureFlash: true
      }),
Rosanny Sihombing's avatar
Rosanny Sihombing committed
69
70
    function (req: any, res: any) {
      res.redirect('/account/')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
71
    }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
72
  )
Rosanny Sihombing's avatar
Rosanny Sihombing committed
73
74
75

  // to generate Service Provider's XML metadata
  app.get('/saml/metadata',
Rosanny Sihombing's avatar
Rosanny Sihombing committed
76
77
78
79
    function (req: any, res: any) {
      res.type('application/xml')
      const spMetadata = samlStrategy.generateServiceProviderMetadata(fs.readFileSync(__dirname + '/cert/cert.pem', 'utf8'))
      res.status(200).send(spMetadata)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
80
    }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
81
  )
Rosanny Sihombing's avatar
Rosanny Sihombing committed
82
83
84

  // ======== APP ROUTES - ACCOUNT ====================

Rosanny Sihombing's avatar
Rosanny Sihombing committed
85
  async function getLoggedInUserData (email: string) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
86
    const user = await dbController.getUserByEmail(email)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
87
88
89
90
    if (!user) {
      console.log('no user found')
      return null
    } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
91
      const loggedInUser = new User(
Rosanny Sihombing's avatar
Rosanny Sihombing committed
92
93
        user.id, email, user.salutation, user.title, user.firstname, user.lastname, user.industry, user.organisation, user.speciality, user.m4lab_idp, user.verificationStatus
      )
Rosanny Sihombing's avatar
Rosanny Sihombing committed
94

Rosanny Sihombing's avatar
Rosanny Sihombing committed
95
      const userGitlabId = await dbController.getGitlabId(loggedInUser.id)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
96
97
98
99
100
101
102
      if (userGitlabId) {
        loggedInUser.setGitlabUserId(userGitlabId)
      }
      return loggedInUser
    }
  }

Rosanny Sihombing's avatar
Rosanny Sihombing committed
103
104
  app.get('/', async function (req: any, res: any) {
    if (!req.isAuthenticated()) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
105
106
      res.redirect('/login')
    } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
107
108
109
110
      const loggedInUser = await getLoggedInUserData(req.user.email)
      if (loggedInUser == null) {
        console.error('user data is not found')
        res.status(500).render(lang + '/500', { error: 'Your data is not found. Please try again.' })
111
      } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
112
        res.render(lang + '/account/home', {
113
          user: loggedInUser
Rosanny Sihombing's avatar
Rosanny Sihombing committed
114
        })
115
      }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
116
    }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
117
  })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
118
119
120
121
122
123
124
125

  app.get('/login',
    passport.authenticate(config.passport.strategy, {
      successRedirect: '/',
      failureRedirect: '/login'
    })
  )

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

Rosanny Sihombing's avatar
Rosanny Sihombing committed
131
132
133
134
    req.user.nameID = req.user.id
    req.user.nameIDFormat = req.user.idFormat
    return samlStrategy.logout(req, function (err: any, uri: any) {
      req.logout()
Rosanny Sihombing's avatar
Rosanny Sihombing committed
135

Rosanny Sihombing's avatar
Rosanny Sihombing committed
136
137
138
139
      if (req.session) {
        req.session.destroy((err: any) => {
          if (err) {
            return console.log(err)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
140
          }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
141
        })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
142
143
      }

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

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

Rosanny Sihombing's avatar
Rosanny Sihombing committed
167
168
  app.get('/services', async function (req: any, res: any) {
    if (!req.isAuthenticated()) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
169
170
      res.redirect('/login')
    } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
171
172
      const loggedInUser = await getLoggedInUserData(req.user.email)
      if (loggedInUser == null) { // null user
Rosanny Sihombing's avatar
Rosanny Sihombing committed
173
174
        res.redirect('/account/')
      } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
175
        if (loggedInUser.getVerificationStatus() !== 1) { // unverified users
Rosanny Sihombing's avatar
Rosanny Sihombing committed
176
177
          res.redirect('/account/')
        } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
178
179
180
181
          const gitlabReposArr = []
          const gitlabPagesArr = []

          if (loggedInUser.getGitlabUserId()) { // for users who have activated their gitlab account
Rosanny Sihombing's avatar
Rosanny Sihombing committed
182
            const userProjects = await gitlabController.getUserProjects(loggedInUser.getGitlabUserId()!)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
183
184
185
186
187
188
189
190
191
192
193
194
195
196
            if (userProjects) {
              let project: any
              for (project in userProjects) {
                if (userProjects[project].tag_list.includes('website')) {
                  const page = {
                    projectInformation: new Website(loggedInUser.getGitlabUserId()!, userProjects[project].name, userProjects[project].description,
                      userProjects[project].id, userProjects[project].avatar_url, userProjects[project].path_with_namespace),
                    pipelineStatus: await gitlabController.getProjectPipelineLatestStatus(userProjects[project].id)
                  }
                  gitlabPagesArr.push(page)
                } else {
                  const repo = new Repo(loggedInUser.getGitlabUserId()!, userProjects[project].name, userProjects[project].description,
                    userProjects[project].id, userProjects[project].avatar_url, userProjects[project].path_with_namespace)
                  gitlabReposArr.push(repo)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
197
198
199
                }
              }
            }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
200
            res.render(lang + '/account/services', {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
201
202
203
204
205
              user: loggedInUser,
              gitlabRepos: gitlabReposArr,
              gitlabPages: gitlabPagesArr
            })
          } else { // for users who have not activated their gitlab account yet
Rosanny Sihombing's avatar
Rosanny Sihombing committed
206
            const gitlabUser = await gitlabController.getUserByEmail(loggedInUser.getEmail())
Rosanny Sihombing's avatar
Rosanny Sihombing committed
207
            if (!gitlabUser) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
208
              res.render(lang + '/account/services', {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
209
210
211
212
213
                user: loggedInUser,
                gitlabRepos: null,
                gitlabPages: null
              })
            } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
214
              const gitlabActivationData = {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
215
                user_id: loggedInUser.getId(),
Rosanny Sihombing's avatar
Rosanny Sihombing committed
216
217
                gitlab_userId: gitlabUser.id
              }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
218

Rosanny Sihombing's avatar
Rosanny Sihombing committed
219
              dbController.addGitlabUser(gitlabActivationData, function (err: any) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
220
221
                if (err) {
                  res.status(500).render(lang + '/500', { error: err })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
222
223
224
225
226
227
228
229
230
231
232
                } else {
                  res.redirect('/account/services')
                }
              })
            }
          }
        }
      }
    }
  })

Rosanny Sihombing's avatar
Rosanny Sihombing committed
233
234
  app.get('/security', async function (req: any, res: any) {
    if (!req.isAuthenticated()) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
235
236
      res.redirect('/login')
    } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
237
238
      const loggedInUser = await getLoggedInUserData(req.user.email)
      if (loggedInUser == null) { // null user
Rosanny Sihombing's avatar
Rosanny Sihombing committed
239
240
        res.redirect('/account/')
      } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
241
        if (loggedInUser.getVerificationStatus() === 1 && loggedInUser.getIdpStatus() === 1) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
242
          res.render(lang + '/account/security', {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
243
244
245
246
247
248
249
250
251
            user: loggedInUser
          })
        } else {
          res.redirect('/account/')
        }
      }
    }
  })

Rosanny Sihombing's avatar
Rosanny Sihombing committed
252
253
  app.post('/updateProfile', async function (req: any, res: any) {
    if (!req.isAuthenticated()) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
254
255
      res.redirect('/login')
    } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
256
257
      const loggedInUser = await getLoggedInUserData(req.user.email)
      if (loggedInUser == null) { // null user
Rosanny Sihombing's avatar
Rosanny Sihombing committed
258
259
        res.redirect('/account/')
      } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
260
        const userData = {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
261
262
263
264
265
266
267
          salutation: req.body.inputSalutation,
          title: req.body.inputTitle,
          firstname: req.body.inputFirstname,
          lastname: req.body.inputLastname,
          email: req.body.inputEmail,
          organisation: req.body.inputOrganisation,
          industry: req.body.inputIndustry,
Rosanny Sihombing's avatar
Rosanny Sihombing committed
268
          speciality: req.body.inputSpeciality
Rosanny Sihombing's avatar
Rosanny Sihombing committed
269
        }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
270
        const result = await dbController.updateUserById(loggedInUser.getId(), userData)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
271
        if (!result) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
272
          res.flash('error', 'Failed')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
273
274
275
276
277
278
279
280
        } else {
          loggedInUser.updateProfile(userData.salutation, userData.title, userData.firstname, userData.lastname, userData.email,
            userData.organisation, userData.industry, userData.speciality)
          res.flash('success', 'Ihr Benutzerprofil wurde aktualisiert!')
        }
        res.redirect('/account/profile')
      }
    }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
281
  })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
282

Rosanny Sihombing's avatar
Rosanny Sihombing committed
283
284
  app.post('/changePwd', async function (req: any, res: any) {
    if (!req.isAuthenticated()) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
285
286
      res.redirect('/login')
    } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
287
      const loggedInUser = await getLoggedInUserData(req.user.email)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
288

Rosanny Sihombing's avatar
Rosanny Sihombing committed
289
      if (loggedInUser == null) { // null user
Rosanny Sihombing's avatar
Rosanny Sihombing committed
290
291
        res.redirect('/account/')
      } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
292
293
294
        const currPwd = req.body.inputCurrPwd
        const newPwd = req.body.inputNewPwd
        const retypePwd = req.body.inputConfirm
Rosanny Sihombing's avatar
Rosanny Sihombing committed
295

Rosanny Sihombing's avatar
Rosanny Sihombing committed
296
        dbConnection.user.query('SELECT password FROM credential WHERE user_id=' + loggedInUser.getId(), function (err: any, rows: any) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
297
298
          if (err) {
            console.error(err)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
299
            res.status(500).render(lang + '/500', { error: err })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
300
          }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
301
          const userPwd = rows[0].password
Rosanny Sihombing's avatar
Rosanny Sihombing committed
302
303

          // check if the password is correct
Rosanny Sihombing's avatar
Rosanny Sihombing committed
304
          bcrypt.compare(currPwd, userPwd, function (err, isMatch) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
305
306
            if (err) {
              console.error(err)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
307
              res.status(500).render(lang + '/500', { error: err })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
308
            } else if (!isMatch) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
309
              res.flash('error', 'Das Passwort ist leider falsch. Bitte überprüfen Sie Ihre Eingabe.')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
310
311
              res.redirect('/account/security')
            } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
312
              if (newPwd !== retypePwd) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
313
314
315
316
                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
Rosanny Sihombing's avatar
Rosanny Sihombing committed
317
318
319
                bcrypt.genSalt(saltRounds, function (err, salt) {
                  bcrypt.hash(newPwd, salt, async function (err, hash) {
                    const credentialData = {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
320
                      password: hash,
Rosanny Sihombing's avatar
Rosanny Sihombing committed
321
                      user_id: loggedInUser.getId()
Rosanny Sihombing's avatar
Rosanny Sihombing committed
322
                    }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
323

Rosanny Sihombing's avatar
Rosanny Sihombing committed
324
                    const result = await dbController.updateCredential(credentialData)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
325
326
                    if (!result) {
                      console.log('Failed to reset password')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
327
                      res.flash('error', 'Datenbankfehler: Passwort kann nicht geändert werden.')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
328
                    } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
329
                      res.flash('success', 'Passwort aktualisiert!')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
330
                      // send notifiaction email
Rosanny Sihombing's avatar
Rosanny Sihombing committed
331
                      mailer.options.to = loggedInUser.getEmail()
Rosanny Sihombing's avatar
Rosanny Sihombing committed
332
333
                      mailer.options.subject = miscConst.updatePasswordMailSubject
                      mailer.options.html = miscConst.updatePasswordMailContent + '<div>' + miscConst.mailSignature + '</div>'
Rosanny Sihombing's avatar
Rosanny Sihombing committed
334
                      mailer.transporter.sendMail(mailer.options, function (err: any) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
335
336
337
338
                        if (err) { console.log(err) }
                      })
                    }
                    res.redirect('/account/security')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
339
340
                  })
                })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
341
342
343
344
345
346
              }
            }
          })
        })
      }
    }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
347
348
349
  })

  app.get('/resendVerificationEmail', async function (req: any, res: any) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
350
351
352
    if (!req.isAuthenticated) {
      res.redirect('/login')
    } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
353
354
      const loggedInUser = await getLoggedInUserData(req.user.email)
      if (loggedInUser == null) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
355
356
        res.redirect('/login')
      } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
357
        const token = await dbController.getVerificationTokenByUserId(loggedInUser.id)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
358
359
360
361
        if (!token) {
          res.send(false)
        } else {
          // send email
Rosanny Sihombing's avatar
Rosanny Sihombing committed
362
363
          const emailSubject = 'Bitte bestätigen Sie Ihr M4_LAB Benutzerkonto'
          const emailContent = '<div>Lieber Nutzer,<br/><br/>' +
Rosanny Sihombing's avatar
Rosanny Sihombing committed
364
365
366
            '<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/>' +
Rosanny Sihombing's avatar
Rosanny Sihombing committed
367
            'Ohne Bestätigung Ihres Kontos müssen wir Ihr Konto leider nach 7 Tagen löschen.</p><br/>' + miscConst.mailSignature +
Rosanny Sihombing's avatar
Rosanny Sihombing committed
368
369
370
371
            '</div>'
          mailer.options.to = loggedInUser.email
          mailer.options.subject = emailSubject
          mailer.options.html = emailContent
Rosanny Sihombing's avatar
Rosanny Sihombing committed
372
          mailer.transporter.sendMail(mailer.options, function (err: any) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
373
374
375
376
377
378
379
380
381
382
383
384
            if (err) {
              console.log('cannot send email')
              throw err
            }
          })
          res.send(true)
        }
      }
    }
  })

  // ============= NEW GITLAB PAGES ===========================
Rosanny Sihombing's avatar
Rosanny Sihombing committed
385
386
387

  app.get('/newInformation', async function (req: any, res: any) {
    if (!req.isAuthenticated()) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
388
389
      res.redirect('/login')
    } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
390
391
      const loggedInUser = await getLoggedInUserData(req.user.email)
      if (loggedInUser == null) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
392
393
        res.redirect('/login')
      } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
394
        const gitlabUser = await gitlabController.getUserByEmail(loggedInUser.getEmail())
Rosanny Sihombing's avatar
Rosanny Sihombing committed
395
396
397
        if (!gitlabUser) { // no user found
          res.redirect('/account/services')
        } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
398
          res.render(lang + '/account/newInformation', {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
399
400
401
402
403
404
405
            user: loggedInUser,
            gitlabUsername: gitlabUser.username
          })
        }
      }
    }
  })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
406
407
  app.post('/newInformation', async function (req: any, res: any) {
    if (!req.isAuthenticated()) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
408
409
      res.redirect('/login')
    } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
410
411
      const loggedInUser = await getLoggedInUserData(req.user.email)
      if (loggedInUser == null) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
412
413
414
415
416
417
        res.redirect('/login')
      } else {
        if (!req.body.name && !req.body.description) {
          res.flash('error', 'Bitte geben Sie die benötigten Daten ein')
          res.redirect('/account/newInformation')
        } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
418
419
420
          const projectName = req.body.name.toLowerCase().replace(/\s/g, '-')
          const projectDesc = req.body.description
          const projectTemplate = req.body.template
Rosanny Sihombing's avatar
Rosanny Sihombing committed
421
          const newInformation = new Website(loggedInUser.getGitlabUserId()!, projectName, projectDesc)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
422
          let newLogoFile = defaultLogo
Rosanny Sihombing's avatar
Rosanny Sihombing committed
423

Rosanny Sihombing's avatar
Rosanny Sihombing committed
424
          if (req.files) { newLogoFile = req.files.logo }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
425

Rosanny Sihombing's avatar
Rosanny Sihombing committed
426
          async.waterfall([
Rosanny Sihombing's avatar
Rosanny Sihombing committed
427
            function (callback: any) { // upload logo
Rosanny Sihombing's avatar
Rosanny Sihombing committed
428
429
430
              if (!req.files) {
                callback(null, newLogoFile)
              } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
431
432
                newLogoFile.mv(logoDir + newLogoFile.name, function (err: any) {
                  newLogoFile = logoDir + newLogoFile.name
Rosanny Sihombing's avatar
Rosanny Sihombing committed
433
434
435
436
                  callback(err, newLogoFile)
                })
              }
            },
Rosanny Sihombing's avatar
Rosanny Sihombing committed
437
            async function (newLogoFile: any) { // create a new GitLab Page
Rosanny Sihombing's avatar
Rosanny Sihombing committed
438
              const newPages = await gitlabController.createNewPages(newInformation, newLogoFile, projectTemplate)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
439
              if (newPages.status) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
440
                if (newPages.data.message.name === 'has already been taken') {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
441
                  res.flash('error', "Der Projektname '" + newInformation.getName() + "' ist bereits vergeben, bitte wählen Sie einen anderen Namen.")
Rosanny Sihombing's avatar
Rosanny Sihombing committed
442
                } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
443
                  res.flash('error', 'Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut. ')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
444
445
446
                }
                res.redirect('/account/newInformation')
              } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
447
448
                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.')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
449
                res.redirect('/account/updateInformation?id=' + String(newPages.id))
Rosanny Sihombing's avatar
Rosanny Sihombing committed
450
451
452
              }
            }
          ], function (err) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
453
            if (err != null) console.log(err)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
454
455
456
            // remove logo
            if (req.files) {
              fs.unlink(newLogoFile, (err) => {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
457
                if (err != null) console.log(err)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
458
459
460
461
462
463
464
465
              })
            }
          })
        }
      }
    }
  })

Rosanny Sihombing's avatar
Rosanny Sihombing committed
466
467
  app.get('/updateInformation', async function (req: any, res: any) {
    if (!req.isAuthenticated()) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
468
469
      res.redirect('/login')
    } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
470
      const loggedInUser = await getLoggedInUserData(req.user.email)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
471

Rosanny Sihombing's avatar
Rosanny Sihombing committed
472
      if (loggedInUser == null) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
473
474
        res.redirect('/login')
      } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
475
        if (!req.query.id) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
476
477
          res.redirect('/account/services')
        } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
478
          const project = await gitlabController.getProjectById(req.query.id)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
479
          if (!project) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
480
            console.log(' ========= Error or no project found')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
481
482
            res.redirect('/account/services')
          } else if (!project.owner) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
483
            console.log(' ========= Project cannot be accessed, since it does not have an owner')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
484
            res.redirect('/account/services')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
485
          } else if (project.owner.id !== loggedInUser.getGitlabUserId()) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
486
            console.log(' ========= Access denied: Not your project')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
487
488
            res.redirect('/account/services')
          } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
489
            const curInformation = new Website(loggedInUser.getGitlabUserId()!, project.name, project.description,
Rosanny Sihombing's avatar
Rosanny Sihombing committed
490
              req.query.id, project.avatar_url, project.path_with_namespace)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
491
492

            res.render(lang + '/account/updateInformation', {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
493
494
495
496
497
498
499
500
501
              user: loggedInUser,
              information: curInformation
            })
          }
        }
      }
    }
  })
  // update a website
Rosanny Sihombing's avatar
Rosanny Sihombing committed
502
503
  app.post('/updateInformation', async function (req: any, res: any) {
    if (!req.isAuthenticated()) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
504
505
      res.redirect('/login')
    } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
506
      const loggedInUser = await getLoggedInUserData(req.user.email)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
507

Rosanny Sihombing's avatar
Rosanny Sihombing committed
508
      if (loggedInUser == null) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
509
510
511
512
513
514
        res.redirect('/login')
      } else {
        if (!req.body.name && !req.body.description) {
          res.flash('error', 'Bitte geben Sie die benötigten Daten ein')
          res.redirect('/account/updateInformation')
        } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
515
516
          const projectName = req.body.name.toLowerCase().replace(/\s/g, '-')
          const projectDesc = req.body.description
Rosanny Sihombing's avatar
Rosanny Sihombing committed
517
          const updatedInformation = new Website(loggedInUser.getGitlabUserId()!, projectName, projectDesc, req.query.id)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
518
519
          let newLogoFile: any

Rosanny Sihombing's avatar
Rosanny Sihombing committed
520
          async.waterfall([
Rosanny Sihombing's avatar
Rosanny Sihombing committed
521
522
            function (callback: any) { // upload logo
              if (!req.files) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
523
524
525
                callback(null, newLogoFile)
              } else {
                newLogoFile = req.files.logo
Rosanny Sihombing's avatar
Rosanny Sihombing committed
526
527
                newLogoFile.mv(logoDir + String(newLogoFile.name), function (err: any) {
                  newLogoFile = logoDir + String(newLogoFile.name)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
528
529
530
531
                  callback(err, newLogoFile)
                })
              }
            },
Rosanny Sihombing's avatar
Rosanny Sihombing committed
532
            async function (newLogoFile: any) { // update gitlab page
Rosanny Sihombing's avatar
Rosanny Sihombing committed
533
              const updatedPages = await gitlabController.updateProject(updatedInformation, newLogoFile)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
534

Rosanny Sihombing's avatar
Rosanny Sihombing committed
535
              if (updatedPages.status) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
536
537
                if (updatedPages.data.message.name === 'has already been taken') {
                  res.flash('error', "Der Projektname '" + String(projectName) + "' ist bereits vergeben, bitte wählen Sie einen anderen Namen.")
Rosanny Sihombing's avatar
Rosanny Sihombing committed
538
                } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
539
                  res.flash('error', 'Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut. ')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
540
541
542
543
                }
              } else {
                updatedInformation.setLogo(updatedPages.avatar_url)
                updatedInformation.setPath(updatedPages.path)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
544
                res.flash('success', 'Ihre Website wurde aktualisiert')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
545
546
              }

Rosanny Sihombing's avatar
Rosanny Sihombing committed
547
              res.redirect('/account/updateInformation?id=' + String(updatedInformation.getId()))
Rosanny Sihombing's avatar
Rosanny Sihombing committed
548
549
            }
          ], function (err) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
550
551
            if (err != null) console.log(err)
            if (newLogoFile) { // remove logo
Rosanny Sihombing's avatar
Rosanny Sihombing committed
552
              fs.unlink(newLogoFile, (err) => {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
553
                if (err != null) console.log(err)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
554
555
556
557
558
559
560
561
              })
            }
          })
        }
      }
    }
  })

Rosanny Sihombing's avatar
Rosanny Sihombing committed
562
563
  app.delete('/deleteProject', async function (req: any, res: any) {
    if (!req.isAuthenticated()) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
564
565
      res.redirect('/login')
    } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
566
567
      const loggedInUser = await getLoggedInUserData(req.user.email)
      if (loggedInUser == null) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
568
569
        res.redirect('/login')
      } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
570
        const projectId = req.body.id
Rosanny Sihombing's avatar
Rosanny Sihombing committed
571
572
573

        if (projectId) {
          // check if the owner is valid
Rosanny Sihombing's avatar
Rosanny Sihombing committed
574
          const project = await gitlabController.getProjectById(projectId)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
575
          if (!project) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
576
            console.log(' ========= Error or no project found')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
577
          } else if (!project.owner) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
578
            console.log(' ========= Project cannot be accessed, since it does not have an owner')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
579
          } else if (project.owner.id !== loggedInUser.getGitlabUserId()) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
580
            console.log(' ========= Access denied: Not your project')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
581
          } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
582
            const isDeleted = await gitlabController.deleteProjectById(projectId)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
583
            if (!isDeleted) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
584
              res.flash('error', 'Project cannot be deleted. Please try again.')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
585
586
587
588
589
590
591
            }
          }
        }
        res.redirect('/account/services')
      }
    }
  })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
592
}