diff --git a/.gitignore b/.gitignore index 14e71094f35ce86e78e4414421a7607bea923540..ad4a42f476eaea40b9f78ca0b1e196518a370c7b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ /built -/routes/cert +/src/routes/cert /node_modules diff --git a/src/functions/methods.ts b/src/controller/dbController.ts similarity index 99% rename from src/functions/methods.ts rename to src/controller/dbController.ts index babef3b47578e8adf9d92374de817335ef7c4c25..2162f10cc21797442ba260032d1d667949410387 100644 --- a/src/functions/methods.ts +++ b/src/controller/dbController.ts @@ -1,6 +1,6 @@ import dbconn = require('../config/dbconn') -const methods = { +const dbController = { // ===================== user db ===================== registerNewUser: function (data: any, callback: any) { dbconn.user.getConnection(function (err: any, thisconn) { @@ -205,4 +205,4 @@ const methods = { } } -export = methods +export { dbController } diff --git a/src/functions/gitlab.ts b/src/controller/gitlabController.ts similarity index 94% rename from src/functions/gitlab.ts rename to src/controller/gitlabController.ts index 4d08518cf54fa30e4863fd6cdf6e2494a1a90a64..647f2a4f0cfd56089ddc25378866bcd51bb54b0c 100644 --- a/src/functions/gitlab.ts +++ b/src/controller/gitlabController.ts @@ -5,7 +5,7 @@ import formData from 'form-data' const env = process.env.NODE_ENV || 'testing' const config = require('../config/config')[env] -const gitlab = { +const gitlabController = { getUserByEmail: async function (email: string) { return await axios({ method: 'get', @@ -24,8 +24,8 @@ const gitlab = { return await axios({ method: 'post', - url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/projects/user/' + newPagesData.getOwnerGitlabId() + - '?name=' + newPagesData.getName() + '&description=' + newPagesData.getDesc() + '&tag_list=website' + + url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/projects/user/' + String(newPagesData.getOwnerGitlabId()) + + '?name=' + String(newPagesData.getName()) + '&description=' + String(newPagesData.getDesc()) + '&tag_list=website' + '&use_custom_template=true&template_name=' + template, headers: { Authorization: 'Bearer ' + config.gitlab.token_readWriteProjects, @@ -124,4 +124,4 @@ const gitlab = { } } -export = gitlab +export {gitlabController} diff --git a/src/controller/publicController.ts b/src/controller/publicController.ts index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..fa52e672eb603bf1228e097c691c2b746dcbc396 100644 --- a/src/controller/publicController.ts +++ b/src/controller/publicController.ts @@ -0,0 +1,64 @@ +import async from 'async' +import mailer from '../config/mailer' +import { dbController } from './dbController' + +const lang = 'DE' + +const publicController = { + showRegistrationPage: function (res: any) { + res.render(lang + '/account/registration') + }, + showContactPage: function (req: any, res: any) { + res.render(lang + '/account/contact', { + user: req.user + }) + }, + showForgotPwdPage: function (req: any, res: any) { + res.render(lang + '/account/forgotPwd', { + user: req.user + }) + }, + showResetToken: async function (req: any, res: any) { + const user = await dbController.getUserByToken(req.params.token) + if (user) { + res.render(lang + '/account/reset') + } else { + res.flash('error', 'Der Schlüssel zum zurücksetzen des Passworts ist ungültig oder abgelaufen.') + res.redirect('/account/forgotPwd') + } + }, + sendContactMessage: function (req: any, res: any) { + 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') + }) + } + ], function (err: any) { + if (!err) { res.flash('success', 'Vielen Dank für Ihre Anfrage. Wir melden uns baldmöglichst bei Ihnen. Eine Kopie Ihrer Anfrage wurde an ' + emailAddress + ' versandt.') } else { + console.error(err) + res.flash('error', 'Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.') + } + res.redirect('/account/contact') + }) + }, + checkUserEmail: async function (req: any, res: any) { + const user = await dbController.checkUserEmail(req.params.email) + if (user) { res.send(false) } else { + res.send(true) + } + } +} + +export { publicController } diff --git a/src/functions/helpers.ts b/src/functions/helpers_TBD.ts similarity index 100% rename from src/functions/helpers.ts rename to src/functions/helpers_TBD.ts diff --git a/src/routes/account.ts b/src/routes/account.ts index 574dc7e694c20ede0ba6208f9a71708850faf7a4..78a5699a55e6e8c9fe85d0a7caf84db93d86df23 100644 --- a/src/routes/account.ts +++ b/src/routes/account.ts @@ -3,8 +3,8 @@ import async from 'async' import bcrypt from 'bcryptjs' import * as passportSaml from 'passport-saml' import dbconn from '../config/dbconn' -import methods from '../functions/methods' -import gitlab from '../functions/gitlab' +import { dbController } from '../controller/dbController' +import { gitlabController } from '../controller/gitlabController' import constants from '../config/const' import mailer from '../config/mailer' import portalUser from '../classes/user' @@ -83,7 +83,7 @@ export = function (app: any, config: any, passport: any, lang: string) { // ======== APP ROUTES - ACCOUNT ==================== async function getLoggedInUserData (email: string) { - const user = await methods.getUserByEmail(email) + const user = await dbController.getUserByEmail(email) if (!user) { console.log('no user found') return null @@ -92,7 +92,7 @@ export = function (app: any, config: any, passport: any, lang: string) { user.id, email, user.salutation, user.title, user.firstname, user.lastname, user.industry, user.organisation, user.speciality, user.m4lab_idp, user.verificationStatus ) - const userGitlabId = await methods.getGitlabId(loggedInUser.id) + const userGitlabId = await dbController.getGitlabId(loggedInUser.id) if (userGitlabId) { loggedInUser.setGitlabUserId(userGitlabId) } @@ -153,7 +153,7 @@ export = function (app: any, config: any, passport: any, lang: string) { if (loggedInUser == null) { // null user res.redirect('/account/') } else { - if (loggedInUser.getVerificationStatus() != 1) { + if (loggedInUser.getVerificationStatus() !== 1) { res.redirect('/account/') } else { res.render(lang + '/account/profile', { @@ -172,14 +172,14 @@ export = function (app: any, config: any, passport: any, lang: string) { if (loggedInUser == null) { // null user res.redirect('/account/') } else { - if (loggedInUser.getVerificationStatus() != 1) { // unverified users + if (loggedInUser.getVerificationStatus() !== 1) { // unverified users res.redirect('/account/') } else { const gitlabReposArr = [] const gitlabPagesArr = [] if (loggedInUser.getGitlabUserId()) { // for users who have activated their gitlab account - const userProjects = await gitlab.getUserProjects(loggedInUser.getGitlabUserId()!) + const userProjects = await gitlabController.getUserProjects(loggedInUser.getGitlabUserId()!) if (!userProjects) { console.error('something went wrong') res.status(500).render(lang + '/500', { error: 'something went wrong' }) @@ -191,7 +191,7 @@ export = function (app: any, config: any, passport: any, lang: string) { const page = { projectInformation: new projectInformation(loggedInUser.getGitlabUserId()!, userProjects[project].name, userProjects[project].description, userProjects[project].id, userProjects[project].avatar_url, userProjects[project].path_with_namespace), - pipelineStatus: await gitlab.getProjectPipelineLatestStatus(userProjects[project].id) + pipelineStatus: await gitlabController.getProjectPipelineLatestStatus(userProjects[project].id) } gitlabPagesArr.push(page) } else { @@ -207,7 +207,7 @@ export = function (app: any, config: any, passport: any, lang: string) { gitlabPages: gitlabPagesArr }) } else { // for users who have not activated their gitlab account yet - const gitlabUser = await gitlab.getUserByEmail(loggedInUser.getEmail()) + const gitlabUser = await gitlabController.getUserByEmail(loggedInUser.getEmail()) if (!gitlabUser) { res.render(lang + '/account/services', { user: loggedInUser, @@ -220,7 +220,7 @@ export = function (app: any, config: any, passport: any, lang: string) { gitlab_userId: gitlabUser.id } - methods.addGitlabUser(gitlabActivationData, function (err: any) { + dbController.addGitlabUser(gitlabActivationData, function (err: any) { if (err) { res.status(500).render(lang + '/500', { error: err }) } else { @@ -242,7 +242,7 @@ export = function (app: any, config: any, passport: any, lang: string) { if (loggedInUser == null) { // null user res.redirect('/account/') } else { - if (loggedInUser.getVerificationStatus() == 1 && loggedInUser.getIdpStatus() == 1) { + if (loggedInUser.getVerificationStatus() === 1 && loggedInUser.getIdpStatus() === 1) { res.render(lang + '/account/security', { user: loggedInUser }) @@ -271,7 +271,7 @@ export = function (app: any, config: any, passport: any, lang: string) { industry: req.body.inputIndustry, speciality: req.body.inputSpeciality } - const result = await methods.updateUserById(loggedInUser.getId(), userData) + const result = await dbController.updateUserById(loggedInUser.getId(), userData) if (!result) { res.flash('error', 'Failed') } else { @@ -325,7 +325,7 @@ export = function (app: any, config: any, passport: any, lang: string) { user_id: loggedInUser.getId() } - const result = await methods.updateCredential(credentialData) + const result = await dbController.updateCredential(credentialData) if (!result) { console.log('Failed to reset password') res.flash('error', 'Datenbankfehler: Passwort kann nicht geändert werden.') @@ -358,7 +358,7 @@ export = function (app: any, config: any, passport: any, lang: string) { if (loggedInUser == null) { res.redirect('/login') } else { - const token = await methods.getVerificationTokenByUserId(loggedInUser.id) + const token = await dbController.getVerificationTokenByUserId(loggedInUser.id) if (!token) { res.send(false) } else { @@ -395,7 +395,7 @@ export = function (app: any, config: any, passport: any, lang: string) { if (loggedInUser == null) { res.redirect('/login') } else { - const gitlabUser = await gitlab.getUserByEmail(loggedInUser.getEmail()) + const gitlabUser = await gitlabController.getUserByEmail(loggedInUser.getEmail()) if (!gitlabUser) { // no user found res.redirect('/account/services') } else { @@ -439,7 +439,7 @@ export = function (app: any, config: any, passport: any, lang: string) { } }, async function (newLogoFile: any) { // create a new GitLab Page - const newPages = await gitlab.createNewPages(newInformation, newLogoFile, projectTemplate) + const newPages = await gitlabController.createNewPages(newInformation, newLogoFile, projectTemplate) if (newPages.status) { 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.") @@ -450,7 +450,7 @@ export = function (app: any, config: any, passport: any, lang: string) { } else { 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.redirect('/account/updateInformation?id=' + newPages.id) + res.redirect('/account/updateInformation?id=' + String(newPages.id)) } } ], function (err) { @@ -479,7 +479,7 @@ export = function (app: any, config: any, passport: any, lang: string) { if (!req.query.id) { res.redirect('/account/services') } else { - const project = await gitlab.getProjectById(req.query.id) + const project = await gitlabController.getProjectById(req.query.id) if (!project) { console.log(' ========= Error or no project found') res.redirect('/account/services') @@ -527,18 +527,18 @@ export = function (app: any, config: any, passport: any, lang: string) { callback(null, newLogoFile) } else { newLogoFile = req.files.logo - newLogoFile.mv(logoDir + newLogoFile.name, function (err: any) { - newLogoFile = logoDir + newLogoFile.name + newLogoFile.mv(logoDir + String(newLogoFile.name), function (err: any) { + newLogoFile = logoDir + String(newLogoFile.name) callback(err, newLogoFile) }) } }, async function (newLogoFile: any) { // update gitlab page - const updatedPages = await gitlab.updateProject(updatedInformation, newLogoFile) + const updatedPages = await gitlabController.updateProject(updatedInformation, newLogoFile) if (updatedPages.status) { - if (updatedPages.data.message.name == 'has already been taken') { - res.flash('error', "Der Projektname '" + projectName + "' ist bereits vergeben, bitte wählen Sie einen anderen Namen.") + 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.") } else { res.flash('error', 'Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut. ') } @@ -575,7 +575,7 @@ export = function (app: any, config: any, passport: any, lang: string) { if (projectId) { // check if the owner is valid - const project = await gitlab.getProjectById(projectId) + const project = await gitlabController.getProjectById(projectId) if (!project) { console.log(' ========= Error or no project found') } else if (!project.owner) { @@ -583,7 +583,7 @@ export = function (app: any, config: any, passport: any, lang: string) { } else if (project.owner.id != loggedInUser.getGitlabUserId()) { console.log(' ========= Access denied: Not your project') } else { - const isDeleted = await gitlab.deleteProjectById(projectId) + const isDeleted = await gitlabController.deleteProjectById(projectId) if (!isDeleted) { res.flash('error', 'Project cannot be deleted. Please try again.') } diff --git a/src/routes/public.ts b/src/routes/public.ts index a41952a8421f2b5bba01cb6eeefa28013b4420b3..151540674670e8b89085291f28f902dd65391574 100644 --- a/src/routes/public.ts +++ b/src/routes/public.ts @@ -1,8 +1,9 @@ import async from 'async' import bcrypt from 'bcryptjs' -import methods from '../functions/methods' +import { dbController } from '../controller/dbController' import mailer from '../config/mailer' import constants from '../config/const' +import { publicController } from '../controller/publicController' const saltRounds: number = 10 const salt: number = 64 @@ -10,7 +11,7 @@ const salt: number = 64 export = function (app: any, config: any, lang: string) { // ================== NEW USERS REGISTRATION ====================== app.get('/registration', function (req: any, res: any) { - res.render(lang + '/account/registration') + publicController.showRegistrationPage(res) }) app.post('/registration', function (req: any, res: any) { // user data @@ -58,7 +59,7 @@ export = function (app: any, config: any, lang: string) { }, // save data function (newAccount: any, err: any) { - methods.registerNewUser(newAccount, function (err: any) { + dbController.registerNewUser(newAccount, function (err: any) { if (err) { res.flash('error', 'Fehlgeschlagen') } else { @@ -66,16 +67,16 @@ export = function (app: any, config: any, lang: string) { const emailSubject = 'Bitte bestätigen Sie Ihr M4_LAB Benutzerkonto' const 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 <a href=' + config.app.host + '/verifyAccount?token=' + newAccount.verificationToken + '>diesen Link</a> ' + + 'Um Ihre Anmeldung zu bestätigen, klicken Sie bitte <a href=' + String(config.app.host) + '/verifyAccount?token=' + String(newAccount.verificationToken) + '>diesen Link</a> ' + '<br/><br/>' + - 'Ohne Bestätigung Ihres Kontos müssen wir Ihr Konto leider nach 7 Tagen löschen.</p><br/>' + constants.mailSignature + + 'Ohne Bestätigung Ihres Kontos müssen wir Ihr Konto leider nach 7 Tagen löschen.</p><br/>' + String(constants.mailSignature) + '</div>' mailer.options.to = req.body.inputEmail mailer.options.subject = emailSubject mailer.options.html = emailContent mailer.transporter.sendMail(mailer.options, function (err: any) { if (err) { - console.error('Cannot send email. [Error] ' + err) + console.error('Cannot send email. [Error] ' + String(err)) throw err } }) @@ -92,20 +93,13 @@ export = function (app: any, config: any, lang: string) { }) // to check whether or not an account is already exist 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) - } + publicController.checkUserEmail(req, res) }) // =================== USERS VERIFICATION ========================= app.get('/verifyAccount', async function (req: any, res: any) { - const userId: number = await methods.getUserIdByVerificationToken(req.query.token) + const userId: number = await dbController.getUserIdByVerificationToken(req.query.token) if (!userId) { // no user found res.render(lang + '/account/verification', { @@ -117,15 +111,15 @@ export = function (app: any, config: any, lang: string) { id: userId, verificationStatus: 1 } - methods.verifyUserAccount(userData, async function (err: any) { + dbController.verifyUserAccount(userData, async function (err: any) { if (err) { - console.log('Error: ' + err) + console.error(err) res.render(lang + '/account/verification', { status: false }) } else { // send welcome email after successful account verification - const userEmail: string = await methods.getUserEmailById(userId) + const userEmail: string = await dbController.getUserEmailById(userId) if (!userEmail) { res.render(lang + '/account/verification', { status: false @@ -158,17 +152,15 @@ export = function (app: any, config: any, lang: string) { // ==================== FORGOT PASSWORD =========================== app.get('/forgotPwd', function (req: any, res: any) { - res.render(lang + '/account/forgotPwd', { - user: req.user - }) + publicController.showForgotPwdPage(req, res) }) app.post('/forgotPwd', function (req: any, res: any) { const emailAddress = req.body.inputEmail async.waterfall([ async function (done: any) { - const user = await methods.checkUserEmail(emailAddress) + const user = await dbController.checkUserEmail(emailAddress) if (!user) { - console.log('No user found: ' + emailAddress) + console.log('No user found: ' + String(emailAddress)) } else { // generate token let token: string = '' @@ -180,15 +172,15 @@ export = function (app: any, config: any, lang: string) { const emailSubject = 'Ihre Passwort-Anfrage an das Transferportal der HFT Stuttgart' const emailContent = '<div>Lieber Nutzer,<br/><br/>' + '<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/>' + - 'Sie können Ihr Passwort mit dem Klick auf diesen Link ändern: ' + config.app.host + '/reset/' + token + '<br/>' + - 'Dieser Link ist aus Sicherheitsgründen nur für 1 Stunde gültig.<br/></p>' + constants.mailSignature + '</div>' + 'Sie können Ihr Passwort mit dem Klick auf diesen Link ändern: ' + String(config.app.host) + '/reset/' + String(token) + '<br/>' + + 'Dieser Link ist aus Sicherheitsgründen nur für 1 Stunde gültig.<br/></p>' + String(constants.mailSignature) + '</div>' const credentialData = { user_id: user.id, resetPasswordToken: token, resetPasswordExpires: Date.now() + 3600000 // 1 hour } - const result = await methods.updateCredential(credentialData) + const result = await dbController.updateCredential(credentialData) if (!result) { console.log('failed to update credential') } else { @@ -207,7 +199,7 @@ export = function (app: any, config: any, lang: string) { 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.flash('success', 'Wenn Ihre E-Mail-Adresse registriert ist, wurde eine E-Mail mit dem weiteren Vorgehen an ' + String(emailAddress) + ' versendet.') } res.redirect('/account/forgotPwd') }) @@ -215,18 +207,12 @@ export = function (app: any, config: any, lang: string) { // reset 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') - } + publicController.showResetToken(req, res) }) app.post('/reset/:token', async function (req: any, res: any) { const newPwd = req.body.inputNewPwd - const user = await methods.getUserByToken(req.params.token) + const user = await dbController.getUserByToken(req.params.token) if (!user) { res.flash('error', 'User not found.') res.redirect('/login') @@ -241,7 +227,7 @@ export = function (app: any, config: any, lang: string) { resetPasswordExpires: null } // update password - const result = await methods.updateCredential(credentialData) + const result = await dbController.updateCredential(credentialData) if (!result) { console.log('Failed to reset password') res.flash('error', 'Datenbankfehler: Passwort kann nicht geändert werden.') @@ -263,37 +249,9 @@ export = function (app: any, config: any, lang: string) { // ======================= CONTACT FORM =========================== app.get('/contact', function (req: any, res: any) { - res.render(lang + '/account/contact', { - user: req.user - }) + publicController.showContactPage(req, res) }) - 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') - }) - } - ], 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') - }) + app.post('/contact', function (req: any, res: any) { + publicController.sendContactMessage(req, res) }) }