public.ts 11.6 KB
Newer Older
Rosanny Sihombing's avatar
Rosanny Sihombing committed
1
2
3
4
5
6
import async from 'async'
import bcrypt from 'bcryptjs'
import methods from '../functions/methods'
import mailer from '../config/mailer'
import constants from '../config/const'

Rosanny Sihombing's avatar
Rosanny Sihombing committed
7
8
const saltRounds: number = 10
const salt: number = 64
Rosanny Sihombing's avatar
Rosanny Sihombing committed
9

Rosanny Sihombing's avatar
Rosanny Sihombing committed
10
export = function (app: any, config: any, lang: string) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
11
  // ================== NEW USERS REGISTRATION ======================
Rosanny Sihombing's avatar
Rosanny Sihombing committed
12
13
  app.get('/registration', function (req: any, res: any) {
    res.render(lang + '/account/registration')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
14
  })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
15
  app.post('/registration', function (req: any, res: any) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
16
    // user data
Rosanny Sihombing's avatar
Rosanny Sihombing committed
17
18
    const curDate: Date = new Date()
    const userData: any = {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
19
20
21
22
23
24
25
26
      salutation: req.body.inputSalutation,
      title: req.body.inputTitle,
      firstname: req.body.inputFirstname,
      lastname: req.body.inputLastname,
      email: req.body.inputEmail,
      organisation: req.body.inputOrganisation,
      industry: req.body.inputIndustry,
      speciality: req.body.inputSpeciality,
Rosanny Sihombing's avatar
Rosanny Sihombing committed
27
      createdDate: curDate.toISOString().slice(0, 10)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
28
    }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
29
30
31
32
33
34
35
36

    const userEmail: any = userData.email
    const pos: number = userEmail.indexOf('@')
    const emailLength: number = userEmail.length
    const emailDomain: any = userEmail.slice(pos, emailLength)

    if (emailDomain.toLowerCase() == '@hft-stuttgart.de') {
      res.flash('error', 'Fehlgeschlagen: HFT-Account')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
37
38
39
      res.redirect('/account/registration')
    } else {
      async.waterfall([
Rosanny Sihombing's avatar
Rosanny Sihombing committed
40
        function (done: any) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
41
          // generate token
Rosanny Sihombing's avatar
Rosanny Sihombing committed
42
43
44
45
          let token: string = ''
          const randomChars: string = 'abcdefghijklmnopqrstuvwxyz0123456789'
          for (let i = 0; i < 40; i++) {
            token += randomChars.charAt(Math.floor(Math.random() * randomChars.length))
Rosanny Sihombing's avatar
Rosanny Sihombing committed
46
47
          }
          // encrypt password
Rosanny Sihombing's avatar
Rosanny Sihombing committed
48
49
50
          bcrypt.genSalt(saltRounds, function (err, salt) {
            bcrypt.hash(req.body.inputPassword, salt, function (err: any, hash: any) {
              const newAccount: any = {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
51
52
53
54
55
                profile: userData,
                password: hash,
                verificationToken: token
              }
              done(err, newAccount)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
56
57
            })
          })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
58
59
        },
        // save data
Rosanny Sihombing's avatar
Rosanny Sihombing committed
60
61
        function (newAccount: any, err: any) {
          methods.registerNewUser(newAccount, function (err: any) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
62
            if (err) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
63
64
              res.flash('error', 'Fehlgeschlagen')
            } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
65
              // send email
Rosanny Sihombing's avatar
Rosanny Sihombing committed
66
67
              const emailSubject = 'Bitte bestätigen Sie Ihr M4_LAB Benutzerkonto'
              const emailContent = '<div>Lieber Nutzer,<br/><br/>' +
Rosanny Sihombing's avatar
Rosanny Sihombing committed
68
                '<p>vielen Dank für Ihre Anmeldung am Transferportal der HFT Stuttgart. <br/>' +
Rosanny Sihombing's avatar
Rosanny Sihombing committed
69
                'Um Ihre Anmeldung zu bestätigen, klicken Sie bitte <a href=' + config.app.host + '/verifyAccount?token=' + newAccount.verificationToken + '>diesen Link</a> ' +
Rosanny Sihombing's avatar
Rosanny Sihombing committed
70
71
                '<br/><br/>' +
                'Ohne Bestätigung Ihres Kontos müssen wir Ihr Konto leider nach 7 Tagen löschen.</p><br/>' + constants.mailSignature +
Rosanny Sihombing's avatar
Rosanny Sihombing committed
72
73
74
75
76
                '</div>'
              mailer.options.to = req.body.inputEmail
              mailer.options.subject = emailSubject
              mailer.options.html = emailContent
              mailer.transporter.sendMail(mailer.options, function (err: any) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
77
                if (err) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
78
                  console.error('Cannot send email. [Error] ' + err)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
79
80
81
82
                  throw err
                }
              })
              // user feedback
Rosanny Sihombing's avatar
Rosanny Sihombing committed
83
84
              res.flash('success', 'Vielen Dank für Ihre Registrierung!' + '\r\n\r\n' +
                'Wir haben Ihnen eine E-Mail an Ihre verwendete Adresse gesendet. Diese enthält einen Link zur Bestätigung Ihres Accounts.' + '\r\n' +
Rosanny Sihombing's avatar
Rosanny Sihombing committed
85
                'Wenn Sie die Mail nicht in ihrem Postfach vorfinden, prüfen Sie bitte auch Ihren Spam-Ordner.')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
86
87
88
            }
            res.redirect('/account/registration')
          })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
89
90
91
92
        }
      ])
    }
  })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
93
  // to check whether or not an account is already exist
Rosanny Sihombing's avatar
Rosanny Sihombing committed
94
95
96
97
98
99
100
101
102
  app.get('/email/:email', async function (req: any, res: any) {
    const user = await methods.checkUserEmail(req.params.email)
    if (!user) {
      console.log('No user found: ' + req.params.email)
      res.send(true)
    } else {
      console.log('User found: ' + req.params.email)
      res.send(false)
    }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
103
  })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
104
105
106

  // =================== USERS VERIFICATION =========================

Rosanny Sihombing's avatar
Rosanny Sihombing committed
107
108
  app.get('/verifyAccount', async function (req: any, res: any) {
    const userId: number = await methods.getUserIdByVerificationToken(req.query.token)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
109
110
    if (!userId) {
      // no user found
Rosanny Sihombing's avatar
Rosanny Sihombing committed
111
      res.render(lang + '/account/verification', {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
112
113
114
115
        status: null
      })
    } else {
      // a user found, verify the account
Rosanny Sihombing's avatar
Rosanny Sihombing committed
116
      const userData: any = {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
117
118
119
        id: userId,
        verificationStatus: 1
      }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
120
      methods.verifyUserAccount(userData, async function (err: any) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
121
        if (err) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
122
123
          console.log('Error: ' + err)
          res.render(lang + '/account/verification', {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
124
            status: false
Rosanny Sihombing's avatar
Rosanny Sihombing committed
125
          })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
126
127
        } else {
          // send welcome email after successful account verification
Rosanny Sihombing's avatar
Rosanny Sihombing committed
128
          const userEmail: string = await methods.getUserEmailById(userId)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
129
          if (!userEmail) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
130
            res.render(lang + '/account/verification', {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
131
132
133
134
              status: false
            })
          } else {
            // send email
Rosanny Sihombing's avatar
Rosanny Sihombing committed
135
136
            const emailSubject = 'Herzlich willkommen'
            const emailContent = '<div>Lieber Nutzer,<br/><br/>' +
137
              '<p>herzlich willkommen beim Transferportal der HFT Stuttgart!<br/>' +
Rosanny Sihombing's avatar
Rosanny Sihombing committed
138
139
140
141
142
              'Sie können nun alle Dienste des Portals nutzen.<p/><br/>' + constants.mailSignature
            mailer.options.to = userEmail
            mailer.options.subject = emailSubject
            mailer.options.html = emailContent
            mailer.transporter.sendMail(mailer.options, function (err: any) {
143
              if (err) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
144
145
                console.log('cannot send email')
                throw err
146
147
              }
            })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
148
149

            res.render(lang + '/account/verification', {
150
151
              status: true
            })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
152
153
          }
        }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
154
      })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
155
156
157
158
159
    }
  })

  // ==================== FORGOT PASSWORD ===========================

Rosanny Sihombing's avatar
Rosanny Sihombing committed
160
161
  app.get('/forgotPwd', function (req: any, res: any) {
    res.render(lang + '/account/forgotPwd', {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
162
163
164
      user: req.user
    })
  })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
165
166
  app.post('/forgotPwd', function (req: any, res: any) {
    const emailAddress = req.body.inputEmail
Rosanny Sihombing's avatar
Rosanny Sihombing committed
167
    async.waterfall([
Rosanny Sihombing's avatar
Rosanny Sihombing committed
168
169
      async function (done: any) {
        const user = await methods.checkUserEmail(emailAddress)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
170
        if (!user) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
171
          console.log('No user found: ' + emailAddress)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
172
173
        } else {
          // generate token
Rosanny Sihombing's avatar
Rosanny Sihombing committed
174
175
176
177
          let token: string = ''
          const randomChars: string = 'abcdefghijklmnopqrstuvwxyz0123456789'
          for (let i = 0; i < 40; i++) {
            token += randomChars.charAt(Math.floor(Math.random() * randomChars.length))
Rosanny Sihombing's avatar
Rosanny Sihombing committed
178
179
          }

Rosanny Sihombing's avatar
Rosanny Sihombing committed
180
181
          const emailSubject = 'Ihre Passwort-Anfrage an das Transferportal der HFT Stuttgart'
          const emailContent = '<div>Lieber Nutzer,<br/><br/>' +
Rosanny Sihombing's avatar
Rosanny Sihombing committed
182
            '<p>wir haben Ihre Anfrage zur Erneuerung Ihres Passwortes erhalten. Falls Sie diese Anfrage nicht gesendet haben, ignorieren Sie bitte diese E-Mail.<br/><br/>' +
Rosanny Sihombing's avatar
Rosanny Sihombing committed
183
            'Sie können Ihr Passwort mit dem Klick auf diesen Link ändern: ' + config.app.host + '/reset/' + token + '<br/>' +
Rosanny Sihombing's avatar
Rosanny Sihombing committed
184
            'Dieser Link ist aus Sicherheitsgründen nur für 1 Stunde gültig.<br/></p>' + constants.mailSignature + '</div>'
Rosanny Sihombing's avatar
Rosanny Sihombing committed
185
186

          const credentialData = {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
187
188
189
190
            user_id: user.id,
            resetPasswordToken: token,
            resetPasswordExpires: Date.now() + 3600000 // 1 hour
          }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
191
          const result = await methods.updateCredential(credentialData)
Rosanny Sihombing's avatar
Rosanny Sihombing committed
192
193
194
195
196
197
198
          if (!result) {
            console.log('failed to update credential')
          } else {
            // send email
            mailer.options.to = emailAddress
            mailer.options.subject = emailSubject
            mailer.options.html = emailContent
Rosanny Sihombing's avatar
Rosanny Sihombing committed
199
            mailer.transporter.sendMail(mailer.options, function (err: any) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
200
201
202
203
204
205
              if (err) { console.error(err) }
            })
          }
        }
        done(null)
      }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
206
    ], function (err: any) {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
207
208
      if (err) {
        res.flash('error', 'Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
209
      } else {
Rosanny Sihombing's avatar
Rosanny Sihombing committed
210
211
212
213
214
215
216
        res.flash('success', 'Wenn Ihre E-Mail-Adresse registriert ist, wurde eine E-Mail mit dem weiteren Vorgehen an ' + emailAddress + ' versendet.')
      }
      res.redirect('/account/forgotPwd')
    })
  })

  // reset
Rosanny Sihombing's avatar
Rosanny Sihombing committed
217
218
219
220
221
222
223
224
  app.get('/reset/:token', async function (req: any, res: any) {
    const user = await methods.getUserByToken(req.params.token)
    if (!user) {
      res.flash('error', 'Der Schlüssel zum zurücksetzen des Passworts ist ungültig oder abgelaufen.')
      res.redirect('/account/forgotPwd')
    } else {
      res.render(lang + '/account/reset')
    }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
225
  })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
226
227
  app.post('/reset/:token', async function (req: any, res: any) {
    const newPwd = req.body.inputNewPwd
Rosanny Sihombing's avatar
Rosanny Sihombing committed
228

Rosanny Sihombing's avatar
Rosanny Sihombing committed
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
    const user = await methods.getUserByToken(req.params.token)
    if (!user) {
      res.flash('error', 'User not found.')
      res.redirect('/login')
    } else {
      // encrypt password
      bcrypt.genSalt(saltRounds, function (err, salt) {
        bcrypt.hash(newPwd, salt, async function (err: any, hash) {
          const credentialData = {
            password: hash,
            user_id: user.user_id,
            resetPasswordToken: null,
            resetPasswordExpires: null
          }
          // update password
          const result = await methods.updateCredential(credentialData)
          if (!result) {
            console.log('Failed to reset password')
            res.flash('error', 'Datenbankfehler: Passwort kann nicht geändert werden.')
          } else {
            res.flash('success', 'Passwort aktualisiert!')
            // send notification email
            mailer.options.to = user.email
            mailer.options.subject = constants.updatePasswordMailSubject
            mailer.options.html = constants.updatePasswordMailContent + '<div>' + constants.mailSignature + '</div>'
            mailer.transporter.sendMail(mailer.options, function (err: any) {
              if (err) { console.log(err) }
            })
          }
          res.redirect('/login')
        })
      })
    }
Rosanny Sihombing's avatar
Rosanny Sihombing committed
262
263
264
  })

  // ======================= CONTACT FORM ===========================
Rosanny Sihombing's avatar
Rosanny Sihombing committed
265
266
  app.get('/contact', function (req: any, res: any) {
    res.render(lang + '/account/contact', {
267
268
      user: req.user
    })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
269
  })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
  app.post('/contact', function (req: any, res: any, next: any) {
    // methods.currentDate();
    const emailAddress = req.body.inputEmail
    const supportAddress = 'support-transfer@hft-stuttgart.de'
    const inputName = req.body.name
    const inputContent = req.body.message
    const emailSubject = 'Ihre Anfrage an das Transferportal'
    const emailContent = '<div>Es wurde eine Anfrage an das Transferportal gestellt: <br/><br/>NAME: ' + inputName + '<br/>NACHRICHT: ' + inputContent + '</div>'
    async.waterfall([
      function (done: any) {
        // send email
        mailer.options.to = supportAddress
        mailer.options.cc = emailAddress
        mailer.options.subject = emailSubject
        mailer.options.html = emailContent
        mailer.transporter.sendMail(mailer.options, function (err: any) {
          done(err, 'done')
Rosanny Sihombing's avatar
Rosanny Sihombing committed
287
        })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
288
289
290
291
292
293
294
295
296
297
      }
    ], function (err: any) {
      if (err) {
        console.error(err)
        res.flash('error', 'Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.')
      } else {
        res.flash('success', 'Vielen Dank für Ihre Anfrage. Wir melden uns baldmöglichst bei Ihnen. Eine Kopie Ihrer Anfrage wurde an ' + emailAddress + ' versandt.')
      }
      res.redirect('/account/contact')
    })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
298
  })
Rosanny Sihombing's avatar
Rosanny Sihombing committed
299
}