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; const salt = 64; // salt length // forgot pwd const async = require('async') const crypto = require('crypto') const mailer = require('./mailer') const logoDir = 'public/upload/' const tpGitlabURL = 'https://transfer.hft-stuttgart.de/gitlab/' const portalUser = require('../classes/user') const projectInformation = require('../classes/website') const projectRepo = require('../classes/repo') module.exports = function (app, config, passport, i18n) { var loggedInUser // =========== PASSPORT ======= passport.serializeUser(function (user, done) { done(null, user); }); passport.deserializeUser(function (user, done) { done(null, user); }); const mailSignature = 'Mit den besten Grüßen,
das Transferportal-Team der HFT Stuttgart

' + 'Transferportal der Hochschule für Technik Stuttgart
' + 'Schellingstr. 24 70174 Stuttgart
' + 'm4lab@hft-stuttgart.de
' + 'https://transfer.hft-stuttgart.de
' + 'HFT  ' + 'Facebook  ' + 'Instagram  ' + 'Twitter  ' + 'Youtube  ' + '' + 'Snapchat' + '
' 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 }, function (profile, done) { return done(null, { id: profile.nameID, idFormat: profile.nameIDFormat, email: profile.email, firstName: profile.givenName, lastName: profile.sn }); }); passport.use(samlStrategy); // ============= SAML ============== app.post(config.passport.saml.path, passport.authenticate(config.passport.strategy, { failureRedirect: '/account/', failureFlash: true }), function (req, res) { res.redirect('/account/'); } ); // to generate Service Provider's XML metadata app.get('/saml/metadata', function(req, res) { res.type('application/xml'); var spMetadata = samlStrategy.generateServiceProviderMetadata(fs.readFileSync(__dirname + '/cert/cert.pem', 'utf8')); res.status(200).send(spMetadata); } ); // ================ test i18n ================== i18n.setLocale('de'); app.get('/de', function(req, res) { var greeting = i18n.__('Hello World') res.send(greeting) }); var lang = 'DE' // ======== APP ROUTES - ACCOUNT ==================== var updatePasswordMailSubject = "Ihr Passwort für das Transferportal wurde gespeichert." var updatePasswordMailContent = '
Lieber Nutzer,

Ihr Passwort wurde erfolgreich geändert.

' + mailSignature + '
'; app.get('/', function (req, res) { if ( !req.isAuthenticated() ) { res.redirect('/login') } else { methods.getUserByEmail(req.user.email, function(data, err){ if (!err) { // Initialize user if (!loggedInUser) { loggedInUser = new portalUser( data.id, req.user.email, data.salutation, data.title, data.firstname, data.lastname, data.industry, data.organisation, data.speciality, data.m4lab_idp, null, data.verificationStatus ) methods.getGitlabId(data.id, function(gitlabUserId, err){ if(!err) { loggedInUser.setGitlabUserId(gitlabUserId) } }) } res.render(lang+'/account/home', { user: loggedInUser }); } }) } }); app.get('/login', passport.authenticate(config.passport.strategy, { successRedirect: '/', failureRedirect: '/login' }) ) app.get('/logout', function (req, res) { if (req.user == null) { return res.redirect('/'); } req.user.nameID = req.user.id; req.user.nameIDFormat = req.user.idFormat; return samlStrategy.logout(req, function(err, uri) { req.logout(); if ( req.session ) { req.session.destroy((err) => { if(err) { return console.log(err); } }); } return res.redirect(uri); }); }); app.get('/profile', function (req, res) { if(!req.isAuthenticated() && !loggedInUser) { res.redirect('/login') } else { if(loggedInUser.getVerificationStatus() != 1) { res.redirect('/account/') } else { res.render(lang+'/account/profile', { user: loggedInUser }) } } }) app.get('/services', function(req, res){ if(!req.isAuthenticated() && !loggedInUser) { res.redirect('/login') } else { if(loggedInUser.getVerificationStatus() != 1) { // unverified users res.redirect('/account/') } else { let gitlabReposArr = [] let gitlabPagesArr = [] if(loggedInUser.getGitlabUserId()) { // for users who have activated their gitlab account async.waterfall([ // check projects in runners function(callback) { let gitlabRunnersProjectIdsArr gitlab.getProjectIdsFromRunners(loggedInUser.getGitlabUserId(), function(data){ if(data.error) return res.status(500).send(data.data) gitlabRunnersProjectIdsArr = data.data callback(null, gitlabRunnersProjectIdsArr) }) } ], function(err, gitlabRunnersProjectIdsArr) { // get user projects gitlab.getUserProjects (loggedInUser.getGitlabUserId(), function(data){ if (data.error) return res.status(500).send(data.data) let gitlabData = data.data for(let i = 0; i < gitlabData.length; i++){ if (gitlabData[i].tag_list.includes('website')) { let idxRunners = gitlabRunnersProjectIdsArr.indexOf(gitlabData[i].id) let isWebsitePublished = false if (idxRunners > 0) { isWebsitePublished = true } let page = new projectInformation(loggedInUser.getGitlabUserId(), gitlabData[i].id, gitlabData[i].name, gitlabData[i].description, gitlabData[i].avatar_url, null, null, isWebsitePublished) gitlabPagesArr.push(page) } else { let repo = new projectRepo(loggedInUser.getGitlabUserId(), gitlabData[i].id, gitlabData[i].name, gitlabData[i].description, gitlabData[i].avatar_url) gitlabReposArr.push(repo) } } res.render(lang+'/account/services', { user: loggedInUser, gitlabRepos: gitlabReposArr, gitlabPages: gitlabPagesArr }) }) }) } else { // for users who have not activated their gitlab account yet gitlab.getUserIdByEmail(loggedInUser.getEmail(), function(data){ if (data.error) { res.status(500).render(lang+'/500', { error: data.data }) } else { let gitlabActivationData = { user_id: loggedInUser.getId(), gitlab_userId: data.data} methods.addGitlabUser(gitlabActivationData, function(err){ if(err) { res.status(500).render(lang+'/500', { error: err }) } else { loggedInUser.setGitlabUserId(gitlabActivationData.gitlab_userId) res.redirect('/account/services') } }) } }) } } } }) app.get('/security', function (req, res) { if (!req.isAuthenticated() && !loggedInUser) { res.redirect('/login') } else { if(loggedInUser.getVerificationStatus() == 1 && loggedInUser.getIdpStatus() == 1) { res.render(lang+'/account/security', { user: loggedInUser }) } else { res.redirect('/account/') } } }) app.post('/updateProfile', function (req, res) { var userData = { 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, } if (!req.isAuthenticated() && !loggedInUser) { res.redirect('/login') } else { if (userData.email) { dbconn.user.query('UPDATE user SET ? WHERE email = "' +userData.email+'"', userData, function (err, rows, fields) { if (err) { res.flash('error', "Failed") } 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'); }) } } }); app.post('/changePwd', function (req, res) { if(!req.isAuthenticated() && !loggedInUser) { res.redirect('/login') } else { var currPwd = req.body.inputCurrPwd var newPwd = req.body.inputNewPwd var retypePwd = req.body.inputConfirm // 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 // 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 mailer.options.subject = updatePasswordMailSubject mailer.options.html = updatePasswordMailContent mailer.transport.sendMail(mailer.options, function(err) { if (err) { console.log(err) } }); } res.redirect('/account/security') }) }); }); } } }) }) } }); app.get('/forgotPwd', function (req, res) { res.render(lang+'/account/forgotPwd', { user: req.user }); }); app.post('/forgotPwd', function(req, res, next) { let emailAddress = req.body.inputEmail async.waterfall([ function(done) { crypto.randomBytes(20, function(err, buf) { var token = buf.toString('hex'); done(err, token); }); }, function(token, done) { methods.checkUserEmail(emailAddress, function(err, user){ if (user) { console.log("email: user found"); var emailSubject = "Ihre Passwort-Anfrage an das Transferportal der HFT Stuttgart"; // var emailContent = "Lieber Nutzer,\n\n"+ // "wir haben Ihre Anfrage zur Erneuerung Ihres Passwortes erhalten. Falls Sie diese Anfrage nicht gesendet haben, ignorieren Sie bitte diese E-Mail.\n\n"+ // "Sie können Ihr Passwort mit dem Klick auf diesen Link ändern: http://localhost:9989/reset/" + token + "\n" + // localhost // "Dieser Link ist aus Sicherheitsgründen nur für 1 Stunde gültig.\n\n"+mailSignature var emailContent = '
Lieber Nutzer, Varun

' + '

wir haben Ihre Anfrage zur Erneuerung Ihres Passwortes erhalten. Falls Sie diese Anfrage nicht gesendet haben, ignorieren Sie bitte diese E-Mail.

' + 'Sie können Ihr Passwort mit dem Klick auf diesen Link ändern: http://m4lab.hft-stuttgart.de/account/reset/' + token + '
' + // test server 'Dieser Link ist aus Sicherheitsgründen nur für 1 Stunde gültig.

' + mailSignature + '
'; var credentialData = { user_id: user.id, resetPasswordToken: token, resetPasswordExpires: Date.now() + 3600000 // 1 hour } methods.updateCredential(credentialData, function(err) { done(err, token, user); }); // send email mailer.options.to = emailAddress; mailer.options.subject = emailSubject; mailer.options.html = emailContent; mailer.transport.sendMail(mailer.options, function(err) { done(err, 'done'); }); } else { done(err, 'no user found'); } }); } ], function(err) { if (err) { res.flash('error', 'Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.'); } else { 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'); }); }); app.get('/reset/:token', function(req, res) { methods.getUserByToken(req.params.token, function(err, user){ 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') } }); }); app.post('/reset/:token', function(req, res) { var newPwd = req.body.inputNewPwd methods.getUserByToken(req.params.token, function(err, user){ if (user) { // encrypt password bcrypt.genSalt(saltRounds, function(err, salt) { bcrypt.hash(newPwd, salt, function(err, hash) { var credentialData = { password: hash, user_id: user.user_id } // update password 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!") // send notifiaction email mailer.options.to = user.email mailer.options.subject = updatePasswordMailSubject mailer.options.html = updatePasswordMailContent mailer.transport.sendMail(mailer.options, function(err) { if (err) { console.log(err) } }); // redirect to login page res.redirect('/login') } }) }); }); } else { res.flash('error', "User not found.") res.redirect('/login') } }); }); // ============= NEW GITLAB PAGES =========================== app.get('/newInformation', function(req, res){ if (!req.isAuthenticated() && !loggedInUser) { res.redirect('/login') } else { res.render(lang+'/account/newInformation', { user: loggedInUser }) } }) app.post('/newInformation', function(req, res) { if(!req.isAuthenticated() && !loggedInUser) { res.redirect('/login') } else { if (!req.body.name && !req.body.description) { res.flash('error', 'Please provide the required data') res.redirect('/account/newInformation') } else { let projectName = req.body.name.toLowerCase().replace(/\s/g, '-') let projectDesc = req.body.description let newInformation = new projectInformation(loggedInUser.getGitlabUserId(), null, projectName, projectDesc, null, null, null, false) if (!req.files) { res.flash('error', 'Please choose a project logo') res.redirect('/account/newInformation') } else { let newLogoFile = req.files.logo async.waterfall([ function(callback){ // upload logo newLogoFile.mv(logoDir + newLogoFile.name, function(err) { newLogoFile = logoDir+newLogoFile.name callback(err, newLogoFile) }) }, function(newLogoFile, callback){ // create a new GitLab Page gitlab.createNewPages(newInformation, newLogoFile, function(data){ let result = data.data if (data.error) { if(result.message.name == "has already been taken") { res.flash("error", "Project name '"+newInformation.getName()+"' has already been taken, please choose another name.") } else { res.flash("error", "Something went wrong. Please try again.") } res.redirect('/account/newInformation') } else { newInformation.setId(result.id) newInformation.setLogo(result.avatar_url) newInformation.setSettingUrl(tpGitlabURL+result.namespace.path+'/'+result.name+'/-/edit/master/public/settings.js') newInformation.setKontaktUrl(tpGitlabURL+result.namespace.path+'/'+result.name+'/-/edit/master/public/kontakt.html') res.flash("success", "Your website has been created, but not published yet. Please continue to Step 2 and Step 3 to have your new website published.") res.redirect('/account/updateInformation?id='+newInformation.getId()) } callback(null) }) } ], function (err) { if(err) console.log(err) // remove logo fs.unlink(newLogoFile, (err) => { if(err) console.log(err) }) }) } } } }) app.get('/updateInformation', function(req, res){ if(!req.isAuthenticated() && !loggedInUser) { res.redirect('/login') } else { if(!req.query.id) { res.redirect('/account/services') } else { gitlab.getUserProjects(loggedInUser.getGitlabUserId(), function(data){ if (data.error) { res.status(500).render(lang+'/500', { error: data.data }) } else { // quick way to decide whether a website is already published or not let informationStatus if(req.query.s != "y" && req.query.s != "n") { res.redirect('/account/services') } else { if(req.query.s == "y") { informationStatus = true } else if(req.query.s == "n") { informationStatus = false } let gitlabData = data.data let curInformation = new projectInformation(loggedInUser.getGitlabUserId(), req.query.id, null, null, null, null, null, informationStatus) for(let i = 0; i < gitlabData.length; i++){ if (gitlabData[i].id == req.query.id) { curInformation.setName(gitlabData[i].name) curInformation.setDesc(gitlabData[i].description) curInformation.setLogo(gitlabData[i].avatar_url) curInformation.setSettingUrl(tpGitlabURL+gitlabData[i].path_with_namespace+'/-/edit/master/public/settings.js') curInformation.setKontaktUrl(tpGitlabURL+gitlabData[i].path_with_namespace+'/-/edit/master/public/kontakt.html') break } } res.render(lang+'/account/updateInformation', { user: loggedInUser, information: curInformation }) } } }) } } }) app.post('/updateInformation', function(req, res){ if(!req.isAuthenticated() && !loggedInUser) { res.redirect('/login') } else { if (!req.body.name && !req.body.description) { res.flash('error', 'Please provide the required data') res.redirect('/account/updateInformation') } else { let projectName = req.body.name.toLowerCase().replace(/\s/g, '-') let projectDesc = req.body.description let updatedInformation = new projectInformation(loggedInUser.getGitlabUserId(), req.query.id, projectName, projectDesc, null, null, null, req.body.isPublished) let newLogoFile async.waterfall([ 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) }) } }, function(newLogoFile, callback){ // update gitlab page gitlab.updateProject(updatedInformation, newLogoFile, function(data){ let result = data.data if (data.error) { if(result.message.name == "has already been taken") { res.flash("error", "Project name has already been taken, please choose another name.") } else { res.flash("error", "Something went wrong. Please try again.") } } else { updatedInformation.setLogo(result.avatar_url) updatedInformation.setSettingUrl(tpGitlabURL+result.namespace.path+'/'+result.name+'/-/edit/master/public/settings.js') updatedInformation.setKontaktUrl(tpGitlabURL+result.namespace.path+'/'+result.name+'/-/edit/master/public/kontakt.html') res.flash("success", "Your website has been updated") } res.redirect('/account/updateInformation?id='+updatedInformation.getId()) callback(null) }) } ], function (err) { if(err) console.log(err) if(newLogoFile){ // remove logo fs.unlink(newLogoFile, (err) => { if(err) console.log(err) }) } }) } } }) // RS: delete projektInformation? app.post('/sendPublishRequest', function(req, res) { if (!req.isAuthenticated() && loggedInUser) { res.redirect('/login') } else { let emailAddress = loggedInUser.getEmail() let supportAddress = "support-transfer@hft-stuttgart.de" let projectName = req.body.projectName let emailContent = "Guten Tag, \n\nhiermit beantrage Ich die Freischaltung einer Webseite auf dem Transferportal für folgendes Projekt: \n" +projectName+"\n\nVielen Dank,\n"+loggedInUser.getFullName() let emailSubject = "M4_LAB New Website Publish Request" async.waterfall([ function(done) { mailer.options.to = supportAddress mailer.options.cc = emailAddress mailer.options.subject = emailSubject mailer.options.text = emailContent mailer.transport.sendMail(mailer.options, function(err) { done(err, 'done') }) } ], function(err) { if (err) { console.log(err) res.send('Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.') } else { res.send('Vielen Dank für Ihre Anfrage. Eine Kopie Ihrer Anfrage wurde an ' + emailAddress + ' versandt.') } }) } }) // ============= NEW USERS REGISTRATION =========================== app.get('/registration', function(req, res) { res.render(lang+'/account/registration') }) app.post('/registration', function(req, res) { // user data var curDate = new Date() var userData = { 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, createdDate: curDate.toISOString().slice(0,10) } var userEmail = userData.email var pos = userEmail.indexOf('@') var emailLength = userEmail.length var emailDomain = userEmail.slice(pos, emailLength); if ( emailDomain.toLowerCase() == "@hft-stuttgart.de") { res.flash('error', "Fehlgeschlagen: HFT-Account") res.redirect('/account/registration') } else { let token async.waterfall([ function(done) { crypto.randomBytes(20, function(err, buf) { token = buf.toString('hex'); done(err, token); }); }, // encrypt password function(token, done) { bcrypt.genSalt(saltRounds, function(err, salt) { bcrypt.hash(req.body.inputPassword, salt, function(err, hash) { var newAccount = { profile: userData, password: hash, verificationToken: token } done(err, newAccount) }); }); }, // save data function(newAccount, err) { methods.registerNewUser(newAccount, function(err){ if (err) { res.flash('error', "Fehlgeschlagen") } else { // send email var emailSubject = "Bitte bestätigen Sie Ihr M4_LAB Benutzerkonto" // var emailContent = "Lieber Nutzer,\n\n"+ // "vielen Dank für Ihre Anmeldung am Transferportal der HFT Stuttgart.\n"+ // "Um Ihre Anmeldung zu bestätigen, klicken Sie bitte diesen Link: "+config.app.host+"/verifyAccount?token="+token+"\n"+ // "Ohne Bestätigung Ihres Kontos müssen wir Ihr Konto leider nach 7 Tagen löschen.\n\n"+ // "Sollten Sie sich selbst nicht mit Ihren Daten am Transferportal registriert haben, ignorieren Sie diese E-Mail bitte.\n\n"+mailSignature var emailContent = '
Lieber Nutzer,

' + '

vielen Dank für Ihre Anmeldung am Transferportal der HFT Stuttgart.
' + 'Um Ihre Anmeldung zu bestätigen, klicken Sie bitte diesen Link: ' + config.app.host + '/verifyAccount?token=' + token + '

' + 'Ohne Bestätigung Ihres Kontos müssen wir Ihr Konto leider nach 7 Tagen löschen.


' + mailSignature + '
'; mailer.options.to = req.body.inputEmail; mailer.options.subject = emailSubject; mailer.options.html = emailContent; mailer.transport.sendMail(mailer.options, function(err) { if (err) { console.log('cannot send email') throw err } }) // user feedback 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'+ 'Wenn Sie die Mail nicht in ihrem Postfach vorfinden, prüfen Sie bitte auch Ihren Spam-Ordner.') } res.redirect('/account/registration') }) } ]) } }) // ============= USER VERIFICATION ================================ app.get("/verifyAccount", function(req, res){ console.log(req.query) methods.getUserIdByVerificationToken(req.query.token, function(userId, err){ if (userId) { let userData = { id: userId, verificationStatus: 1 } methods.verifyUserAccount(userData, function(err){ if (err) { console.log("Error: "+err) res.render(lang+'/account/verification', { status: false }); } else { // send welcome email after successful account verification methods.getUserById(userId, function(data, err){ if (err) { console.log("Error: "+err) } else { // send email var emailSubject = "Herzlich willkommen" var emailContent = '
Lieber Nutzer,

' + '

herzlich willkommen beim Transferportal der HFT Stuttgart!
' + 'Sie können nun alle Dienste des Portals nutzen.


' + mailSignature; mailer.options.to = data.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 } }) } }) if(!loggedInUser) { loggedInUser.setVerificationStatus(userData.verificationStatus) } res.render(lang+'/account/verification', { status: true }); } }) } else { res.render(lang+'/account/verification', { status: null }); } }) }) app.get("/resendVerificationEmail", function(req, res){ if (req.isAuthenticated()) { var emailAddress = req.user.email methods.getUserIdByEmail(req.user.email, function(userId, err) { if (!err) { // get token methods.getVerificationTokenByUserId(userId, function(token, err){ if (!err) { if (token) { // send email var emailSubject = "Bitte bestätigen Sie Ihr M4_LAB Benutzerkonto" // var emailContent = "Lieber Nutzer,\n\n"+ // "vielen Dank für Ihre Anmeldung am Transferportal der HFT Stuttgart. "+ // "\nUm Ihre Anmeldung zu bestätigen, klicken Sie bitte diesen Link: "+config.app.host+"/verifyAccount?token="+token+ // "\n\nOhne Bestätigung Ihres Kontos müssen wir Ihr Konto leider nach 7 Tagen löschen.\n\n"+mailSignature var emailContent = '

Lieber Nutzer,

' + '

vielen Dank für Ihre Anmeldung am Transferportal der HFT Stuttgart.
' + 'Um Ihre Anmeldung zu bestätigen, klicken Sie bitte diesen Link: ' + config.app.host + '/verifyAccount?token=' + token + '

' + 'Ohne Bestätigung Ihres Kontos müssen wir Ihr Konto leider nach 7 Tagen löschen.


' + mailSignature + '
'; mailer.options.to = emailAddress; mailer.options.subject = emailSubject; mailer.options.html = emailContent; mailer.transport.sendMail(mailer.options, function(err) { if (err) { console.log('cannot send email') throw err } }) res.send(true) } else { res.send(false) } } else { console.log(err) } }) } }) } }) app.get('/email/:email', function(req, res) { methods.checkUserEmail(req.params.email, function(err, user){ if (!err) { if (user) { res.send(false) } else { res.send(true) } } }) }) app.get('/contact', function (req, res) { res.render(lang+'/account/contact', { user: req.user }) }) app.post('/contact', function(req, res, next) { //methods.currentDate(); let emailAddress = req.body.inputEmail; let supportAddress = "support-transfer@hft-stuttgart.de"; let inputName = req.body.name; let inputContent = req.body.message; let emailContent = "Es wurde eine Anfrage an das Transferportal gestellt: \n\n NAME: " + inputName + "\n NACHRICHT:\n "+ inputContent; let emailSubject = "Ihre Anfrage an das Transferportal"; async.waterfall([ function(done) { // send email mailer.options.to = supportAddress; mailer.options.cc = emailAddress; mailer.options.subject = emailSubject; mailer.options.text = emailContent; mailer.transport.sendMail(mailer.options, function(err) { done(err, 'done'); }); } ], function(err) { if (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') }) }) }