Commit 8361c2c4 authored by Rosanny Sihombing's avatar Rosanny Sihombing
Browse files

Merge branch 'MLAB-383' into 'testing'

Mlab 383

See merge request !70
parents 5c72b939 16289931
Pipeline #2593 passed with stage
in 24 seconds
const gitlab = require('../routes/gitlab')
//const axios = require('axios')
//jest.mock('axios')
describe('GitLab API', () => {
test('returns an existing gitlab user by an email address', async () => {
let user = await gitlab.getUserByEmail('putavaliduseremailaddress@here.com')
expect(user).not.toBeNull()
})
test('returns an undefined user', async () => {
let user = await gitlab.getUserByEmail('johndoe@nowhere.com')
expect(user).toBeUndefined()
})
test('returns users project', async () => {
let userProjects = await gitlab.getUserProjects('put a valid user id in integer here')
expect(userProjects).toBeDefined()
})
test('returns undefined projects, due to non-existing gitlab user ID', async () => {
let userProjects = await gitlab.getUserProjects(0)
expect(userProjects).toBeUndefined()
})
test('returns a project by ID', async () => {
let project = await gitlab.getProjectById(13) // m4lab_landing_page
expect(project).toBeDefined()
})
test('returns undefined, due to invalid project ID', async () => {
let project = await gitlab.getProjectById(0)
expect(project).toBeUndefined()
})
})
\ No newline at end of file
const methods = require('../routes/methods')
describe("DB methohds test", () => {
it('returns a user from DB by email', done => {
methods.getUserByEmail('rosanny.sihombing@hft-stuttgart.de', function(resp, err){
try {
expect(resp).not.toBeNull()
expect(err).toBeNull()
done()
} catch (error) {
done(error)
}
})
})
it("returns a user from DB by ID", done => {
methods.getUserById(10, function(resp, err){
try {
expect(resp).not.toBeNull()
expect(err).toBeNull()
done()
} catch (error) {
done(error)
}
})
})
it("checks user email", done => {
methods.checkUserEmail("test@email.de", function(err, resp){
try {
expect(resp).not.toBeNull()
expect(err).toBeNull()
done()
} catch (error) {
done(error)
}
})
})
it("returns a user by token", done => {
methods.checkUserEmail("1abc0qwerty", function(err, resp){ // token = any alphanumeric
try {
expect(resp).not.toBeNull()
expect(err).toBeNull()
done()
} catch (error) {
done(error)
}
})
})
})
...@@ -7,7 +7,7 @@ const cookieParser = require('cookie-parser'); ...@@ -7,7 +7,7 @@ const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser'); const bodyParser = require('body-parser');
const session = require('express-session'); const session = require('express-session');
const errorhandler = require('errorhandler'); const errorhandler = require('errorhandler');
const flash = require('express-flash'); const flash = require('express-flash-2');
const fileUpload = require('express-fileupload'); const fileUpload = require('express-fileupload');
const helmet = require('helmet'); const helmet = require('helmet');
const compression = require('compression'); const compression = require('compression');
...@@ -56,12 +56,6 @@ app.use(session( ...@@ -56,12 +56,6 @@ app.use(session(
} }
)); ));
app.use(flash()); app.use(flash());
app.use((req, res, next) => {
res.locals.errors = req.flash("error");
res.locals.successes = req.flash("success");
next();
});
app.use(passport.initialize()); app.use(passport.initialize());
app.use(passport.session()); app.use(passport.session());
...@@ -73,11 +67,9 @@ app.use(function(req, res, next) { ...@@ -73,11 +67,9 @@ app.use(function(req, res, next) {
}); });
require('./routes/routes-account')(app, config, passport, i18n); require('./routes/routes-account')(app, config, passport, i18n);
require('./routes/api')(app, config, passport);
// Handle 404 // Handle 404
app.use(function (req, res, next) { app.use(function (req, res, next) {
//res.status(404).send('404: Page not Found', 404)
res.status(404).render('./DE/404') res.status(404).render('./DE/404')
}) })
......
class Project {
constructor(ownerGitlabId, id, name, desc, logo, path) {
this.ownerGitlabId = ownerGitlabId
this.id = id
this.name = name
this.desc = desc
this.logo = logo
this.path = path
}
// getter
getOwnerGitlabId() {
return this.ownerGitlabId
}
getId() {
return this.id
}
getName() {
return this.name
}
getDesc() {
return this.desc
}
getLogo() {
return this.logo
}
getPath() {
return this.path
}
// setter
setOwnerGitlabId(newOwnerGitlabId){
this.ownerGitlabId = newOwnerGitlabId
}
setId(newId) {
this.id = newId
}
setName(newName) {
this.name = newName
}
setDesc(newDesc) {
this.desc = newDesc
}
setLogo(newLogoUrl) {
this.logo = newLogoUrl
}
setPath(newPath) {
this.path = newPath
}
}
module.exports = Project
\ No newline at end of file
const Project = require("./project");
class Repo extends Project {
constructor(ownerGitlabId, id, name, desc, logo, path) {
super(ownerGitlabId, id, name, desc, logo, path)
}
}
module.exports = Repo
\ No newline at end of file
class User {
constructor(id, email, salutation, title, firstName, lastName, industry, organisation, speciality, is_m4lab_idp, gitlabUserId, verificationStatus) {
this.id = id
this.email = email
this.salutation = salutation
this.title = title
this.firstName = firstName
this.lastName = lastName
this.industry = industry
this.organisation = organisation
this.speciality = speciality
this.is_m4lab_idp = is_m4lab_idp // 1 or 0
this.gitlabUserId = gitlabUserId
this.verificationStatus = verificationStatus
}
// getter
getId() {
return this.id
}
getEmail() {
return this.email
}
getFullName() {
return this.firstName+' '+this.lastName
}
getIdpStatus() {
return this.is_m4lab_idp
}
getGitlabUserId() {
return this.gitlabUserId
}
getVerificationStatus() {
return this.verificationStatus
}
// setter
setEmail(email) {
this.email = email
}
setSalutation(salutation) {
this.salutation = salutation
}
setTitle(title) {
this.title = title
}
setFirstName(firstName) {
this.firstName = firstName
}
setLastName(lastName) {
this.lastName = lastName
}
setIndustry(industry) {
this.industry = industry
}
setOrganisation(organisation) {
this.organisation = organisation
}
setSpeciality(speciality) {
this.speciality = speciality
}
setM4lab_idp(m4lab_idp) {
this.m4lab_idp = m4lab_idp
}
setGitlabUserId(newGitlabUserId) {
this.gitlabUserId = newGitlabUserId
}
setVerificationStatus(verificationStatus) {
this.verificationStatus = verificationStatus
}
updateProfile(newSalutation, newTitle, newFirstname, newLastname, newEmail, newOrganisation, newIndustry, newSpeciality) {
this.salutation = newSalutation
this.title = newTitle
this.firstName = newFirstname
this.lastName = newLastname
this.email = newEmail
this.organisation = newOrganisation
this.industry = newIndustry
this.speciality = newSpeciality
}
}
module.exports = User
\ No newline at end of file
const Project = require("./project");
class Website extends Project {
constructor(ownerGitlabId, id, name, desc, logo, path) {
super(ownerGitlabId, id, name, desc, logo, path)
}
}
module.exports = Website
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -17,10 +17,11 @@ ...@@ -17,10 +17,11 @@
}, },
"scripts": { "scripts": {
"start": "nodemon app.js", "start": "nodemon app.js",
"test": "" "test": "jest"
}, },
"dependencies": { "dependencies": {
"async": "^3.1.0", "async": "^3.1.0",
"axios": "^0.21.1",
"bcryptjs": "^2.4.3", "bcryptjs": "^2.4.3",
"body-parser": "^1.19.0", "body-parser": "^1.19.0",
"compression": "^1.7.4", "compression": "^1.7.4",
...@@ -29,19 +30,20 @@ ...@@ -29,19 +30,20 @@
"errorhandler": "1.4.3", "errorhandler": "1.4.3",
"express": "^4.17.1", "express": "^4.17.1",
"express-fileupload": "^1.1.6", "express-fileupload": "^1.1.6",
"express-flash": "0.0.2", "express-flash-2": "^1.0.1",
"express-session": "^1.17.0", "express-session": "^1.17.0",
"form-data": "^3.0.0",
"fs": "0.0.1-security", "fs": "0.0.1-security",
"helmet": "^3.23.3", "helmet": "^3.23.3",
"i18n": "^0.8.5", "i18n": "^0.8.5",
"jest": "^26.6.3",
"morgan": "^1.9.1", "morgan": "^1.9.1",
"mysql": "^2.17.1", "mysql": "^2.17.1",
"nodemailer": "^6.3.1", "nodemailer": "^6.3.1",
"nodemon": "^2.0.1", "nodemon": "^2.0.1",
"passport": "0.3.2", "passport": "0.3.2",
"passport-saml": "^1.4.2", "passport-saml": "^1.4.2",
"pug": "^2.0.4", "pug": "^3.0.2"
"superagent": "^6.1.0"
}, },
"devDependencies": {}, "devDependencies": {},
"engines": { "engines": {
......
...@@ -17,13 +17,6 @@ userConnection.connect(function(err) { ...@@ -17,13 +17,6 @@ userConnection.connect(function(err) {
if (err) throw err; if (err) throw err;
}) })
userConnection.query('USE '+config.database.dbUser) userConnection.query('USE '+config.database.dbUser)
// user db connection test
userConnection.query('SELECT 1 + 5 AS solution', function (err, rows, fields) {
if (err) throw err
console.log('Solution = ', rows[0].solution)
})
//userConnection.end()
// ALTERNATIVE approach: close db connection manually after every query // ALTERNATIVE approach: close db connection manually after every query
/* /*
...@@ -62,13 +55,6 @@ projectConnection.connect(function(err) { ...@@ -62,13 +55,6 @@ projectConnection.connect(function(err) {
if (err) throw err; if (err) throw err;
}) })
projectConnection.query('USE '+config.database.dbProject) projectConnection.query('USE '+config.database.dbProject)
// projectdb connection test
projectConnection.query('SELECT 10 + 5 AS project', function (err, rows, fields) {
if (err) throw err
console.log('Project = ', rows[0].project)
})
//projectConnection.end()
var connection = { var connection = {
user: userConnection, user: userConnection,
......
var env = process.env.NODE_ENV || 'testing'
const config = require('../config/config')[env]
const axios = require('axios')
const fs = require('fs')
var formData = require('form-data')
var gitlab = {
// todo: GraphQL currentUser
getUserByEmail: async function(email) {
return axios({
method: 'get',
url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/users?search='+email,
headers: {
'Authorization': 'Bearer '+config.gitlab.token_readWriteProjects}
})
.then(res => userData = {
id: res.data[0].id,
username: res.data[0].username
})
.catch(err => console.error(err))
},
createNewPages: async function(newPagesData, newLogoFile, template) {
let data = new formData()
data.append('avatar', fs.createReadStream(newLogoFile))
return 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'+
'&use_custom_template=true&template_name='+template,
headers: {
'Authorization': 'Bearer '+config.gitlab.token_readWriteProjects,
...data.getHeaders()
},
data: data
})
.then(res => res = {
error: false,
data: res.data
})
.catch(err => res = {
error: true,
data: err.response.data
})
},
updateProject: async function(updatedProjectData, newLogoFile){
let data = new formData()
if (newLogoFile) {
data.append('avatar', fs.createReadStream(newLogoFile))
}
return axios({
method: 'put',
url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/projects/'+updatedProjectData.getId()+
'?name='+updatedProjectData.getName()+'&description='+updatedProjectData.getDesc(),
headers: {
'Authorization': 'Bearer '+config.gitlab.token_readWriteProjects,
...data.getHeaders()
},
data : data
})
.then(res => res = {
error: false,
data: res.data
})
.catch(err => res = {
error: true,
data: err.response.data
})
},
getUserProjects: async function(gitlabUserId) {
return axios({
method: 'get',
url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/users/'+gitlabUserId+'/projects?private_token='+
config.gitlab.token_readWriteProjects+'&owned=true&simple=true&visibility=public'
})
.then(res => res.data)
.catch(err => console.error(err))
},
getProjectById: async function(projectId) {
return axios({
method: 'get',
url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/projects/'+projectId+'?private_token='+
config.gitlab.token_readWriteProjects
})
.then(res => res.data)
.catch(err => console.error(err))
},
getProjectPipelineLatestStatus: async function(projectId) {
return axios({
method: 'get',
url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/projects/'+projectId+'/pipelines'
})
.then(res => res.data[0].status)
.catch(err => console.error(err))
},
// delete peoject: https://docs.gitlab.com/ee/api/projects.html#delete-project
//
// test GraphQL
getGraphqlTest: function(callback) {
axios({
url: 'https://gitlab.com/api/graphql',
method: 'get',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer '+config.gitlab.token_readWriteProjects
},
data: {
query: `{
currentUser {
id
username
}
}`
/* query: `{
projects {
nodes {
id
}
}
}` */
}
}).then((result) => {
console.log(JSON.stringify(result.data))
});
}
}
module.exports = gitlab
\ No newline at end of file
const dbconn = require('./dbconn'); const dbconn = require('./dbconn');
var methods = { var methods = {
// test method
currentDate: function() {
console.log('Current Date is: ' + new Date().toISOString().slice(0, 10));
},
// ===================== user db ===================== // ===================== user db =====================
registerNewUser: function(data, callback) { registerNewUser: function(data, callback) {
dbconn.user.beginTransaction(function(err) { // START TRANSACTION dbconn.user.beginTransaction(function(err) { // START TRANSACTION
...@@ -70,22 +66,20 @@ var methods = { ...@@ -70,22 +66,20 @@ var methods = {
}, },
getUserByEmail: function(email, callback) { getUserByEmail: function(email, callback) {
dbconn.user.query('SELECT id, verificationStatus, salutation, title, firstname, lastname, industry, organisation, speciality, m4lab_idp FROM user WHERE email = "' +email+'"', function (err, rows, fields) { dbconn.user.query('SELECT id, verificationStatus, salutation, title, firstname, lastname, industry, organisation, speciality, m4lab_idp FROM user WHERE email = "' +email+'"', function (err, rows, fields) {
if (err) { let user
throw err; if (err) { throw err }
}
else { else {
if ( rows.length > 0) { if ( rows.length > 0) {
user = rows[0]; user = rows[0]
} }
} }
callback(user, err); callback(user, err)
}); });
}, },
getUserById: function(userId, callback) { getUserById: function(userId, callback) {
dbconn.user.query('SELECT verificationStatus, email, salutation, title, firstname, lastname, industry, organisation, speciality FROM user WHERE id = ' +userId, function (err, rows, fields) { dbconn.user.query('SELECT verificationStatus, email, salutation, title, firstname, lastname, industry, organisation, speciality FROM user WHERE id = ' +userId, function (err, rows, fields) {
if (err) { let user
throw err; if (err) { throw err }
}
else { else {
if ( rows.length > 0) { if ( rows.length > 0) {
user = rows[0]; user = rows[0];
...@@ -96,34 +90,29 @@ var methods = { ...@@ -96,34 +90,29 @@ var methods = {
}, },
checkUserEmail: function(email, callback) { checkUserEmail: function(email, callback) {
let user let user
dbconn.user.query('SELECT id, email FROM user WHERE email = "' +email+'"', function (err, rows, fields) { dbconn.user.query('SELECT id, email FROM user WHERE email = "' +email+'"', function (err, rows) {
if (err) { if (err) { throw err }
throw err;
}
else { else {
if ( rows.length > 0) { if ( rows.length > 0) {
user = rows[0]; user = rows[0];
} }
} }
callback(err, user); callback(err, user)
}); });
}, },
getUserByToken: function(token, callback) { getUserByToken: function(token, callback) {
let user let user
dbconn.user.query('SELECT t1.user_id, t2.email FROM userdb.credential AS t1 INNER JOIN userdb.user AS t2 ON t1.user_id = t2.id AND t1.resetPasswordToken = "' dbconn.user.query('SELECT t1.user_id, t2.email FROM userdb.credential AS t1 INNER JOIN userdb.user AS t2 ON t1.user_id = t2.id AND t1.resetPasswordToken = "'
+token+'" and resetPasswordExpires > '+Date.now(), function (err, rows, fields) { +token+'" and resetPasswordExpires > '+Date.now(), function (err, rows, fields) {
if (err) { if (err) { throw err }
throw err;
}
else { else {
if ( rows.length > 0) { if ( rows.length > 0) {
user = rows[0] user = rows[0]
console.log(user)
} }
} }
callback(err, user); callback(err, user)
} }
); )
}, },
updateUserById: function(userData, callback) { updateUserById: function(userData, callback) {
dbconn.user.query('UPDATE user SET ? WHERE id = ' +userData.id, userData, function (err, rows, fields) { dbconn.user.query('UPDATE user SET ? WHERE id = ' +userData.id, userData, function (err, rows, fields) {
......
...@@ -2,6 +2,7 @@ const fs = require('fs') ...@@ -2,6 +2,7 @@ const fs = require('fs')
const SamlStrategy = require('passport-saml').Strategy const SamlStrategy = require('passport-saml').Strategy
const dbconn = require('./dbconn') const dbconn = require('./dbconn')
const methods = require('./methods') const methods = require('./methods')
const gitlab = require('./gitlab')
// pwd encryption // pwd encryption
const bcrypt = require('bcryptjs'); const bcrypt = require('bcryptjs');
const saltRounds = 10; const saltRounds = 10;
...@@ -10,10 +11,18 @@ const salt = 64; // salt length ...@@ -10,10 +11,18 @@ const salt = 64; // salt length
const async = require('async') const async = require('async')
const crypto = require('crypto') const crypto = require('crypto')
const mailer = require('./mailer') const mailer = require('./mailer')
const superagent = require('superagent') const logoDir = 'public/upload/'
const tpGitlabURL = 'https://transfer.hft-stuttgart.de/gitlab/'
const tpGitlabPagesURL = 'https://transfer.hft-stuttgart.de/pages/'
const portalUser = require('../classes/user')
const projectInformation = require('../classes/website')
const projectRepo = require('../classes/repo')
module.exports = function (app, config, passport, i18n) { module.exports = function (app, config, passport, i18n) {
var loggedInUser
// =========== PASSPORT ======= // =========== PASSPORT =======
passport.serializeUser(function (user, done) { passport.serializeUser(function (user, done) {
done(null, user); done(null, user);
...@@ -101,35 +110,39 @@ module.exports = function (app, config, passport, i18n) { ...@@ -101,35 +110,39 @@ module.exports = function (app, config, passport, i18n) {
// ======== APP ROUTES - ACCOUNT ==================== // ======== APP ROUTES - ACCOUNT ====================
var updatePasswordMailSubject = "Ihr Passwort für das Transferportal wurde gespeichert." var updatePasswordMailSubject = "Ihr Passwort für das Transferportal wurde gespeichert."
// var mailSignature = "Mit den besten Grüßen,\ndas Transferportal-Team der HFT Stuttgart\n\n"+
// "Transferportal der Hochschule für Technik Stuttgart\n"+
// "Schellingstr. 24\n"+
// "70174 Stuttgart\n"+
// "m4lab@hft-stuttgart.de\n"+
// "https://transfer.hft-stuttgart.de"
var updatePasswordMailContent = '<div>Lieber Nutzer,<br/><br/>Ihr Passwort wurde erfolgreich geändert.<br/><br/>' + mailSignature + '</div>'; var updatePasswordMailContent = '<div>Lieber Nutzer,<br/><br/>Ihr Passwort wurde erfolgreich geändert.<br/><br/>' + mailSignature + '</div>';
app.get('/', function (req, res) { app.get('/', function (req, res) {
if (req.isAuthenticated()) { if ( !req.isAuthenticated() ) {
res.redirect('/login')
} else {
methods.getUserByEmail(req.user.email, function(data, err){ methods.getUserByEmail(req.user.email, function(data, err){
if (!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', { res.render(lang+'/account/home', {
user: data user: loggedInUser
}); });
} }
}) })
} else {
res.redirect('/login'); // localhost
} }
}); });
app.get('/login', app.get('/login',
passport.authenticate(config.passport.strategy, passport.authenticate(config.passport.strategy, {
{ successRedirect: '/',
successRedirect: '/', failureRedirect: '/login'
failureRedirect: '/login' })
}) )
);
app.get('/logout', function (req, res) { app.get('/logout', function (req, res) {
if (req.user == null) { if (req.user == null) {
...@@ -154,156 +167,87 @@ module.exports = function (app, config, passport, i18n) { ...@@ -154,156 +167,87 @@ module.exports = function (app, config, passport, i18n) {
}); });
app.get('/profile', function (req, res) { app.get('/profile', function (req, res) {
if (req.isAuthenticated()) { if(!req.isAuthenticated() && !loggedInUser) {
methods.getUserByEmail(req.user.email, function(data, err){ res.redirect('/login')
if (!err) {
if (data.verificationStatus == 1) {
console.log(data)
res.render(lang+'/account/profile', {
user: data,
email: req.user.email
})
}
else {
res.render(lang+'/account/home', {
user: data
});
}
}
})
} else { } else {
res.redirect('/login'); if(loggedInUser.getVerificationStatus() != 1) {
res.redirect('/account/')
} else {
res.render(lang+'/account/profile', {
user: loggedInUser
})
}
} }
}); })
app.get('/services', function (req, res) { app.get('/services', async function(req, res){
if (req.isAuthenticated()) { if(!req.isAuthenticated() && !loggedInUser) {
methods.getUserByEmail(req.user.email, function(data, err){ res.redirect('/login')
if (!err) { } else {
if (data.verificationStatus == 1) { if(loggedInUser.getVerificationStatus() != 1) { // unverified users
// start =============== RS: MLAB-183 res.redirect('/account/')
let userId = data.id } else {
methods.getGitlabId(userId, function(data, err){ let gitlabReposArr = []
if (!err) { let gitlabPagesArr = []
if (data) {
console.log("TODO: GitLab is already activated for this user. Allow project creation.") if(loggedInUser.getGitlabUserId()) { // for users who have activated their gitlab account
} let userProjects = await gitlab.getUserProjects(loggedInUser.getGitlabUserId())
else { if (!userProjects)
superagent.get('https://transfer.hft-stuttgart.de/gitlab/api/v4/users?private_token='+config.gitlab.token_readWriteProjects+'&search='+req.user.email) res.status(500).send("something went wrong :/")
.then(res => {
if (res.body.length > 0) { for (project in userProjects) {
let gitlabActivationData = { if (userProjects[project].tag_list.includes('website')) {
user_id: userId, let page = {
gitlab_userId: res.body[0].id projectInformation: new projectInformation(loggedInUser.getGitlabUserId(), userProjects[project].id, userProjects[project].name,
} userProjects[project].description, userProjects[project].avatar_url, userProjects[project].path_with_namespace),
methods.addGitlabUser(gitlabActivationData, function(err){}) pipelineStatus: await gitlab.getProjectPipelineLatestStatus(userProjects[project].id)
}
else {
console.log('TODO: Show gitlab activation button: transfer.hft-stuttgart.de/gitlab')
}
})
.catch(err => {
console.log(err.message)
});
}
}
})
// end =============== RS: MLAB-183
res.render(lang+'/account/services', {
user: data
});
/* !!! DO NOT DELETE. TEMPORARILY DISABLED FOR FUTURE USE. !!!
async.waterfall([
// get userId by email from userdb
function(done) {
methods.getUserIdByEmail(req.user.email, function(userId, err) {
if (!err) {
done(err, userId)
}
})
},
// get user-project-role from userdb
function(userId, done) {
methods.getUserProjectRole(userId, function(userProjects, err) {
if (!err) {
done(err, userProjects)
}
})
},
// get all projects from projectdb
function(userProjects, done) {
methods.getAllProjects(function(projectsOverview, err) {
if (!err) {
done(err, userProjects, projectsOverview)
}
})
},
// create JSON object of projects and user status for front-end
function(userProjects, projectsOverview, done) {
var allProjects = [] // JSON object
var userProjectId = [] // array of user's project_id
for (var i = 0; i < userProjects.length; i++) {
userProjectId.push(userProjects[i].project_id)
}
for (var i = 0; i < projectsOverview.length; i++) {
// check if projectId is exist in userProjectId[]
var status = false
if (userProjectId.indexOf(projectsOverview[i].id) > -1) {
status = true
}
// add data to JSON object
allProjects.push({
id: projectsOverview[i].id,
title: projectsOverview[i].title,
summary: projectsOverview[i].onelinesummary,
cp: projectsOverview[i].contact_email,
userStatus: status
});
}
// render the page
res.render(lang+'/account/services', {
user: data,
project: allProjects
});
} }
]) gitlabPagesArr.push(page)
*/ } else {
} let repo = new projectRepo(loggedInUser.getGitlabUserId(), userProjects[project].id, userProjects[project].name,
else { userProjects[project].description, userProjects[project].avatar_url, userProjects[project].path_with_namespace)
res.render(lang+'/account/home', { gitlabReposArr.push(repo)
user: data }
});
} }
res.render(lang+'/account/services', {
user: loggedInUser,
gitlabRepos: gitlabReposArr,
gitlabPages: gitlabPagesArr
})
} else { // for users who have not activated their gitlab account yet
let gitlabUser = await gitlab.getUserByEmail(loggedInUser.getEmail())
// RS: if error, then what?
let gitlabActivationData = {
user_id: loggedInUser.getId(),
gitlab_userId: gitlabUser.id}
// RS: update to await
methods.addGitlabUser(gitlabActivationData, function(err){
if(err) {
res.status(500).render(lang+'/500', { error: err })
} else {
loggedInUser.setGitlabUserId(gitlabActivationData.gitlab_userId)
res.redirect('/account/services')
}
})
} }
}) }
} else {
res.redirect('/login');
} }
}); })
app.get('/security', function (req, res) { app.get('/security', function (req, res) {
if (req.isAuthenticated()) { if (!req.isAuthenticated() && !loggedInUser) {
methods.getUserByEmail(req.user.email, function(data, err){ res.redirect('/login')
if (!err) {
if (data.verificationStatus == 1 && data.m4lab_idp == 1) {
res.render(lang+'/account/security', {
user: data
})
}
else {
res.render(lang+'/account/home', {
user: data
});
}
}
})
} else { } else {
res.redirect('/login'); if(loggedInUser.getVerificationStatus() == 1 && loggedInUser.getIdpStatus() == 1) {
res.render(lang+'/account/security', {
user: loggedInUser
})
} else {
res.redirect('/account/')
}
} }
}); })
app.post('/updateProfile', function (req, res) { app.post('/updateProfile', function (req, res) {
var userData = { var userData = {
...@@ -317,104 +261,83 @@ module.exports = function (app, config, passport, i18n) { ...@@ -317,104 +261,83 @@ module.exports = function (app, config, passport, i18n) {
speciality: req.body.inputSpeciality, speciality: req.body.inputSpeciality,
} }
if (req.isAuthenticated()) { if (!req.isAuthenticated() && !loggedInUser) {
res.redirect('/login')
} else {
if (userData.email) { if (userData.email) {
dbconn.user.query('UPDATE user SET ? WHERE email = "' +userData.email+'"', userData, function (err, rows, fields) { dbconn.user.query('UPDATE user SET ? WHERE email = "' +userData.email+'"', userData, function (err, rows, fields) {
//if (err) throw err;
if (err) { if (err) {
req.flash('error', "Failed"); res.flash('error', "Failed")
} }
else { else {
//req.flash('success', 'Profile updated!'); loggedInUser.updateProfile(userData.salutation, userData.title, userData.firstname, userData.lastname, userData.email,
req.flash('success', 'Ihr Benutzerprofil wurde aktualisiert!'); userData.organisation, userData.industry, userData.speciality)
res.flash('success', 'Ihr Benutzerprofil wurde aktualisiert!')
} }
res.redirect('/account/profile'); res.redirect('/account/profile');
}) })
} }
} else {
res.redirect('/login');
} }
}); });
app.post('/changePwd', function (req, res) { app.post('/changePwd', function (req, res) {
if (req.isAuthenticated()) { if(!req.isAuthenticated() && !loggedInUser) {
res.redirect('/login')
} else {
var currPwd = req.body.inputCurrPwd var currPwd = req.body.inputCurrPwd
var newPwd = req.body.inputNewPwd var newPwd = req.body.inputNewPwd
var retypePwd = req.body.inputConfirm var retypePwd = req.body.inputConfirm
methods.getUserIdByEmail(req.user.email, function(userId, err) { // update - get userId from loggedInUser
if (!err) { dbconn.user.query('SELECT password FROM credential WHERE user_id='+loggedInUser.getId(), function (err, rows, fields) {
// Load hashed passwd from DB if (err) {
dbconn.user.query('SELECT password FROM credential WHERE user_id='+userId, function (err, rows, fields) { console.error(err)
if (err) { res.status(500).render(lang+'/500', { error: err })
console.error(err) }
res.status(500).render(lang+'/500', { var userPwd = rows[0].password
error: err
})
}
var userPwd = rows[0].password
// check if the password is correct // check if the password is correct
bcrypt.compare(currPwd, userPwd, function(err, isMatch) { bcrypt.compare(currPwd, userPwd, function(err, isMatch) {
if (err) { if (err) {
console.error(err) console.error(err)
res.status(500).render(lang+'/500', { res.status(500).render(lang+'/500', { error: err })
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 (!isMatch) { } else {
//req.flash('error', "Sorry, your password was incorrect. Please double-check your password.") if ( newPwd != retypePwd ) {
req.flash('error', "Das Passwort ist leider falsch. Bitte überprüfen Sie Ihre Eingabe.") res.flash('error', 'Passwörter stimmen nicht überein. Bitte stellen Sie sicher, dass Sie das Passwort beide Male genau gleich eingeben.')
//res.redirect('/security') res.redirect('/account/security')
res.redirect('/account/security') } else {
} // update password
else { bcrypt.genSalt(saltRounds, function(err, salt) {
if ( newPwd != retypePwd ) { bcrypt.hash(newPwd, salt, function(err, hash) {
//req.flash('error', "Passwords do no match. Please make sure you re-type your new password correctly.") var credentialData = {
req.flash('error', 'Passwörter stimmen nicht überein. Bitte stellen Sie sicher, dass Sie das Passwort beide Male genau gleich eingeben.') password: hash,
res.redirect('/account/security') user_id: userId
} }
else { methods.updateCredential(credentialData, function(err){
// update password if (err) {
bcrypt.genSalt(saltRounds, function(err, salt) { res.flash('error', "Datenbankfehler: Passwort kann nicht geändert werden.")
bcrypt.hash(newPwd, salt, function(err, hash) { throw err
var credentialData = { } else {
password: hash, res.flash('success', "Passwort aktualisiert!")
user_id: userId mailer.options.to = req.user.email
} mailer.options.subject = updatePasswordMailSubject
methods.updateCredential(credentialData, function(err){ mailer.options.html = updatePasswordMailContent
if (err) { mailer.transport.sendMail(mailer.options, function(err) {
//req.flash('error', "Database error: Password cannot be modified.") if (err) { console.log(err) }
req.flash('error', "Datenbankfehler: Passwort kann nicht geändert werden.") });
throw err }
} res.redirect('/account/security')
else { })
//req.flash('success', "Pasword updated!") });
req.flash('success', "Passwort aktualisiert!") });
mailer.options.to = req.user.email }
//mailOptions.subject = "Your M4_LAB Password has been updated." }
mailer.options.subject = updatePasswordMailSubject
mailer.options.html = updatePasswordMailContent
mailer.transport.sendMail(mailer.options, function(err) {
if (err) {
console.log(err)
}
});
}
res.redirect('/account/security')
})
});
});
}
}
})
}) })
}
}) })
} }
else {
res.redirect('/login');
}
}); });
app.get('/forgotPwd', function (req, res) { app.get('/forgotPwd', function (req, res) {
...@@ -424,14 +347,7 @@ module.exports = function (app, config, passport, i18n) { ...@@ -424,14 +347,7 @@ module.exports = function (app, config, passport, i18n) {
}); });
app.post('/forgotPwd', function(req, res, next) { app.post('/forgotPwd', function(req, res, next) {
//methods.currentDate(); let emailAddress = req.body.inputEmail
var emailAddress = req.body.inputEmail;
/* var emailContent = "Hi there,\n\n"+
"we've received a request to reset your password. However, this email address is not on our database of registered users.\n\n"+
"Thanks,\nM4_LAB Team";
var emailSubject = "Account Access Attempted"; */
async.waterfall([ async.waterfall([
function(done) { function(done) {
crypto.randomBytes(20, function(err, buf) { crypto.randomBytes(20, function(err, buf) {
...@@ -443,17 +359,10 @@ module.exports = function (app, config, passport, i18n) { ...@@ -443,17 +359,10 @@ module.exports = function (app, config, passport, i18n) {
methods.checkUserEmail(emailAddress, function(err, user){ methods.checkUserEmail(emailAddress, function(err, user){
if (user) { if (user) {
console.log("email: user found"); console.log("email: user found");
//var emailSubject = "M4_LAB Password Reset";
var emailSubject = "Ihre Passwort-Anfrage an das Transferportal der HFT Stuttgart"; var emailSubject = "Ihre Passwort-Anfrage an das Transferportal der HFT Stuttgart";
/* var emailContent = "Hi User,\n\n"+
"we've received a request to reset your password. If you didn't make the request, just ignore this email.\n\n"+
"Otherwise, you can reset your password using this link: http://m4lab.hft-stuttgart.de/account/reset/" + token + "\n" +
"This password reset is only valid for 1 hour.\n\n"+
"Thanks,\nM4_LAB Team" */
// var emailContent = "Lieber Nutzer,\n\n"+ // 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"+ // "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://m4lab.hft-stuttgart.de/account/reset/" + token + "\n" + // test server // "Sie können Ihr Passwort mit dem Klick auf diesen Link ändern: http://localhost:9989/reset/" + token + "\n" + // localhost
// //"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 // "Dieser Link ist aus Sicherheitsgründen nur für 1 Stunde gültig.\n\n"+mailSignature
var emailContent = '<div>Lieber Nutzer, Varun<br/><br/>' + var emailContent = '<div>Lieber Nutzer, Varun<br/><br/>' +
...@@ -479,35 +388,29 @@ module.exports = function (app, config, passport, i18n) { ...@@ -479,35 +388,29 @@ module.exports = function (app, config, passport, i18n) {
}); });
} }
else { else {
//done(err, null, null);
done(err, 'no user found'); done(err, 'no user found');
} }
}); });
} }
], function(err) { ], function(err) {
if (err) { if (err) {
//req.flash('error', 'An error occured. Please try again.'); res.flash('error', 'Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.');
req.flash('error', 'Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.');
} }
else { else {
//req.flash('success', 'If your email is registered, an e-mail has been sent to ' + emailAddress + ' with further instructions.'); res.flash('success', 'Wenn Ihre E-Mail-Adresse registriert ist, wurde eine E-Mail mit dem weiteren Vorgehen an ' + emailAddress + ' versendet.');
req.flash('success', 'Wenn Ihre E-Mail-Adresse registriert ist, wurde eine E-Mail mit dem weiteren Vorgehen an ' + emailAddress + ' versendet.');
} }
//res.redirect('/forgotPwd'); // deployment res.redirect('/account/forgotPwd');
res.redirect('/account/forgotPwd'); // localhost
}); });
}); });
app.get('/reset/:token', function(req, res) { app.get('/reset/:token', function(req, res) {
methods.getUserByToken(req.params.token, function(err, user){ methods.getUserByToken(req.params.token, function(err, user){
if (!user) { if (!user) {
//req.flash('error', 'Password reset token is invalid or has expired.'); res.flash('error', 'Der Schlüssel zum zurücksetzen des Passworts ist ungültig oder abgelaufen.')
req.flash('error', 'Der Schlüssel zum zurücksetzen des Passworts ist ungültig oder abgelaufen.'); res.redirect('/account/forgotPwd')
//res.redirect('/forgotPwd'); // deployment
res.redirect('/account/forgotPwd'); // deployment
} }
else { else {
res.render(lang+'/account/reset'); res.render(lang+'/account/reset')
} }
}); });
}); });
...@@ -526,13 +429,11 @@ module.exports = function (app, config, passport, i18n) { ...@@ -526,13 +429,11 @@ module.exports = function (app, config, passport, i18n) {
// update password // update password
methods.updateCredential(credentialData, function(err){ methods.updateCredential(credentialData, function(err){
if (err) { if (err) {
//req.flash('error', "Database error: Password cannot be modified.") res.flash('error', "Datenbankfehler: Passwort kann nicht geändert werden.")
req.flash('error', "Datenbankfehler: Passwort kann nicht geändert werden.")
throw err throw err
} }
else { else {
//req.flash('success', "Your pasword has been updated.") res.flash('success', "Passwort aktualisiert!")
req.flash('success', "Passwort aktualisiert!")
// send notifiaction email // send notifiaction email
mailer.options.to = user.email mailer.options.to = user.email
mailer.options.subject = updatePasswordMailSubject mailer.options.subject = updatePasswordMailSubject
...@@ -550,13 +451,167 @@ module.exports = function (app, config, passport, i18n) { ...@@ -550,13 +451,167 @@ module.exports = function (app, config, passport, i18n) {
}); });
} }
else { else {
req.flash('error', "User not found.") res.flash('error', "User not found.")
res.redirect('/login') res.redirect('/login')
} }
}); });
}); });
// ============= NEW GITLAB PAGES ===========================
app.get('/newInformation', async function(req, res){
if (!req.isAuthenticated() && !loggedInUser) {
res.redirect('/login')
} else {
let gitlabUser = await gitlab.getUserByEmail(loggedInUser.getEmail())
if (!gitlabUser) { // no user found
res.redirect('/account/service')
} else {
res.render(lang+'/account/newInformation', {
user: loggedInUser,
gitlabUsername: gitlabUser.username
})
}
}
})
app.post('/newInformation', function(req, res) {
if(!req.isAuthenticated() && !loggedInUser) {
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 {
let projectName = req.body.name.toLowerCase().replace(/\s/g, '-')
let projectDesc = req.body.description
let projectTemplate = req.body.template
let newInformation = new projectInformation(loggedInUser.getGitlabUserId(), null, projectName, projectDesc, null, null)
if (!req.files) {
res.flash('error', 'Bitte geben Sie ein Projektlogo an.')
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)
})
},
async function(newLogoFile){ // create a new GitLab Page
let newPages = await gitlab.createNewPages(newInformation, newLogoFile, projectTemplate)
if (newPages.error) {
if(newPages.data.message.name == "has already been taken") {
res.flash("error", "Der Projektname '"+newInformation.getName()+"' ist bereits vergeben, bitte wählen Sie einen anderen Namen.")
} else {
res.flash("error", "Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut. ")
}
res.redirect('/account/newInformation')
} else {
let newPagesData = newPages.data
//res.flash("success", "Ihre Webseite wurde erstellt, aber noch nicht veröffentlicht. Bitte fahren Sie mit Schritten 2 und 3 fort, um Ihre Webseite zu veröffentlichen.")
res.flash("success", "Your website will be published AFTER you complete your website by following the provided guideline below."+
"\r\n Your website URL: "+tpGitlabPagesURL+newPagesData.path_with_namespace+"/home/")
res.redirect('/account/updateInformation?id='+newPagesData.id)
}
}
], function (err) {
if(err) console.log(err)
// remove logo
fs.unlink(newLogoFile, (err) => {
if(err) console.log(err)
})
})
}
}
}
})
app.get('/updateInformation', async function(req, res){
if(!req.isAuthenticated() && !loggedInUser) {
res.redirect('/login')
} else {
if(!req.query.id) {
res.redirect('/account/services')
} else {
let project = await gitlab.getProjectById(req.query.id)
if (!project) {
console.log(" =================== error or no project found")
res.redirect('/account/services')
} else if (project.owner.id != loggedInUser.getGitlabUserId()) {
console.log(" =================== not your project")
res.redirect('/account/services')
} else {
let curInformation = new projectInformation(loggedInUser.getGitlabUserId(), req.query.id, project.name, project.description,
project.avatar_url, project.path_with_namespace)
res.render(lang+'/account/updateInformation', {
user: loggedInUser,
information: curInformation
})
}
}
}
})
app.post('/updateInformation', function(req, res){
if(!req.isAuthenticated() && !loggedInUser) {
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 {
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)
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)
})
}
},
async function(newLogoFile, callback){ // update gitlab page
let updatedPages = await gitlab.updateProject(updatedInformation, newLogoFile)
let pagesData = updatedPages.data
if (pagesData.error) {
if(pagesData.message.name == "has already been taken") {
res.flash("error", "Der Projektname ist bereits vergeben, bitte wählen Sie einen anderen Namen.")
} else {
res.flash("error", "Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut. ")
}
} else {
updatedInformation.setLogo(pagesData.avatar_url)
updatedInformation.setPath(pagesData.path)
res.flash("success", "Your website has been updated")
}
res.redirect('/account/updateInformation?id='+updatedInformation.getId())
}
], function (err) {
if(err) console.log(err)
if(newLogoFile){ // remove logo
fs.unlink(newLogoFile, (err) => {
if(err) console.log(err)
})
}
})
}
}
})
// RS: delete projektInformation?
// ============= NEW USERS REGISTRATION =========================== // ============= NEW USERS REGISTRATION ===========================
app.get('/registration', function(req, res) { app.get('/registration', function(req, res) {
res.render(lang+'/account/registration') res.render(lang+'/account/registration')
...@@ -582,8 +637,8 @@ module.exports = function (app, config, passport, i18n) { ...@@ -582,8 +637,8 @@ module.exports = function (app, config, passport, i18n) {
var emailDomain = userEmail.slice(pos, emailLength); var emailDomain = userEmail.slice(pos, emailLength);
if ( emailDomain.toLowerCase() == "@hft-stuttgart.de") { if ( emailDomain.toLowerCase() == "@hft-stuttgart.de") {
req.flash('error', "Fehlgeschlagen: HFT-Account") res.flash('error', "Fehlgeschlagen: HFT-Account")
res.redirect('/account/registration'); res.redirect('/account/registration')
} }
else { else {
let token let token
...@@ -611,7 +666,7 @@ module.exports = function (app, config, passport, i18n) { ...@@ -611,7 +666,7 @@ module.exports = function (app, config, passport, i18n) {
function(newAccount, err) { function(newAccount, err) {
methods.registerNewUser(newAccount, function(err){ methods.registerNewUser(newAccount, function(err){
if (err) { if (err) {
req.flash('error', "Fehlgeschlagen") res.flash('error', "Fehlgeschlagen")
} }
else { else {
// send email // send email
...@@ -637,7 +692,7 @@ module.exports = function (app, config, passport, i18n) { ...@@ -637,7 +692,7 @@ module.exports = function (app, config, passport, i18n) {
} }
}) })
// user feedback // user feedback
req.flash('success', 'Vielen Dank für Ihre Registrierung!'+'\r\n\r\n'+ 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'+ '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.') 'Wenn Sie die Mail nicht in ihrem Postfach vorfinden, prüfen Sie bitte auch Ihren Spam-Ordner.')
} }
...@@ -673,9 +728,6 @@ module.exports = function (app, config, passport, i18n) { ...@@ -673,9 +728,6 @@ module.exports = function (app, config, passport, i18n) {
else { else {
// send email // send email
var emailSubject = "Herzlich willkommen" var emailSubject = "Herzlich willkommen"
// var emailContent = "Lieber Nutzer,\n\n"+
// "herzlich willkommen beim Transferportal der HFT Stuttgart!\n"+
// "Sie können nun alle Dienste des Portals nutzen.\n\n"+mailSignature
var emailContent = '<div>Lieber Nutzer,<br/><br/>' + var emailContent = '<div>Lieber Nutzer,<br/><br/>' +
'<p>herzlich willkommen beim Transferportal der HFT Stuttgart!<br/>' + '<p>herzlich willkommen beim Transferportal der HFT Stuttgart!<br/>' +
'Sie können nun alle Dienste des Portals nutzen.<p/><br/>' + mailSignature; 'Sie können nun alle Dienste des Portals nutzen.<p/><br/>' + mailSignature;
...@@ -691,6 +743,9 @@ module.exports = function (app, config, passport, i18n) { ...@@ -691,6 +743,9 @@ module.exports = function (app, config, passport, i18n) {
} }
}) })
if(!loggedInUser) {
loggedInUser.setVerificationStatus(userData.verificationStatus)
}
res.render(lang+'/account/verification', { res.render(lang+'/account/verification', {
status: true status: true
}); });
...@@ -764,12 +819,12 @@ module.exports = function (app, config, passport, i18n) { ...@@ -764,12 +819,12 @@ module.exports = function (app, config, passport, i18n) {
}) })
app.get('/contact', function (req, res) { app.get('/contact', function (req, res) {
res.render(lang+'/account/contact', { res.render(lang+'/account/contact', {
user: req.user user: req.user
}); })
}); })
app.post('/contact', function(req, res, next) { app.post('/contact', function(req, res, next) {
//methods.currentDate(); //methods.currentDate();
let emailAddress = req.body.inputEmail; let emailAddress = req.body.inputEmail;
let supportAddress = "support-transfer@hft-stuttgart.de"; let supportAddress = "support-transfer@hft-stuttgart.de";
...@@ -790,13 +845,13 @@ module.exports = function (app, config, passport, i18n) { ...@@ -790,13 +845,13 @@ module.exports = function (app, config, passport, i18n) {
} }
], function(err) { ], function(err) {
if (err) { if (err) {
req.flash('error', 'Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.'); res.flash('error', 'Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.');
} }
else { else {
req.flash('success', 'Vielen Dank für Ihre Anfrage. Wir melden uns baldmöglichst bei Ihnen. Eine Kopie Ihrer Anfrage wurde an ' + emailAddress + ' versandt.'); 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('/forgotPwd'); // deployment res.redirect('/account/contact')
res.redirect('/account/contact'); // localhost })
}); })
});
}; }
\ No newline at end of file \ No newline at end of file
...@@ -17,14 +17,12 @@ html(lang="de") ...@@ -17,14 +17,12 @@ html(lang="de")
div(class="col-md-12" style="margin-bottom: 40px;") div(class="col-md-12" style="margin-bottom: 40px;")
img(class="mx-auto" src="/img/Kontakt.jpg" width="100%") img(class="mx-auto" src="/img/Kontakt.jpg" width="100%")
div(class="contact-clean" style="background-color: rgb(234,234,234);") div(class="contact-clean" style="background-color: rgb(234,234,234);")
if successes if flash.success
for success in successes div.alert.alert-success.alert-dismissible #{flash.success}
div.alert.alert-success.alert-dismissible #{ success } a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
a(class="close", href="#", data-dismiss="alert", aria-label="close") &times; if flash.error
if errors div.alert.alert-danger.alert-dismissible.fade.show #{flash.error}
for error, i in errors a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
div.alert.alert-danger.alert-dismissible.fade.show #{ error }
a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
form(method="POST") form(method="POST")
h2(class="text_center") Kontaktieren Sie uns h2(class="text_center") Kontaktieren Sie uns
div(class="form-group") div(class="form-group")
......
...@@ -12,14 +12,12 @@ html(lang="de") ...@@ -12,14 +12,12 @@ html(lang="de")
div(class="container-fluid") div(class="container-fluid")
div(class="row") div(class="row")
div(class="col-md-6 offset-md-3") div(class="col-md-6 offset-md-3")
if successes if flash.success
for success in successes div.alert.alert-success.alert-dismissible #{flash.success}
div.alert.alert-success.alert-dismissible #{ success } a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
a(class="close", href="#", data-dismiss="alert", aria-label="close") &times; if flash.error
if errors div.alert.alert-danger.alert-dismissible.fade.show #{flash.error}
for error, i in errors a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
div.alert.alert-danger.alert-dismissible.fade.show #{ error }
a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
form#forgotForm(class="form-signin", method="POST") form#forgotForm(class="form-signin", method="POST")
img(src="https://transfer.hft-stuttgart.de/images/demo/m4lab_logo.jpg", class="img-responsive center-block", width="185", height="192") img(src="https://transfer.hft-stuttgart.de/images/demo/m4lab_logo.jpg", class="img-responsive center-block", width="185", height="192")
div(class="form-row") div(class="form-row")
......
...@@ -25,12 +25,12 @@ html(lang="de") ...@@ -25,12 +25,12 @@ html(lang="de")
ul(class="flex-md-column flex-row navbar-nav w-100 justify-content-between") ul(class="flex-md-column flex-row navbar-nav w-100 justify-content-between")
li(class="nav-item") li(class="nav-item")
a(class="nav-link pl-0 text-nowrap" href="#") a(class="nav-link pl-0 text-nowrap" href="#")
span(class="font-weight-bold" style="color:black;") #{user.firstname} #{user.lastname} span(class="font-weight-bold" style="color:black;") #{user.firstName} #{user.lastName}
li(class="nav-item") li(class="nav-item")
a(class="nav-link pl-0" href="/account/profile") a(class="nav-link pl-0" href="/account/profile")
i(class="fa fa-user fa-fw") i(class="fa fa-user fa-fw")
span(class="d-none d-md-inline") Benutzerprofil span(class="d-none d-md-inline") Benutzerprofil
if user.m4lab_idp == 1 if user.is_m4lab_idp
li(class="nav-item") li(class="nav-item")
a(class="nav-link pl-0" href="/account/security") a(class="nav-link pl-0" href="/account/security")
i(class="fa fa-lock fa-fw") i(class="fa fa-lock fa-fw")
......
doctype html
html(lang="de")
head
title= "Setup a new website"
meta(charset="UTF-8")
meta(name="viewport", content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no")
link(rel="stylesheet", type="text/css", href="/css/bootstrap.min.css")
link(rel="stylesheet", type="text/css", href="/css/m4lab.css")
link(rel="stylesheet", href="https://use.fontawesome.com/releases/v5.8.2/css/all.css", integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay", crossorigin="anonymous")
body
div(class="container")
div(class="row min-vh-100 flex-column flex-md-row")
aside(class="col-12 col-md-3 p-0 flex-shrink-1")
nav(class="navbar navbar-expand flex-md-column flex-row align-items-start py-2")
div(class="collapse navbar-collapse")
ul(class="flex-md-column flex-row navbar-nav w-100 justify-content-between")
li(class="nav-item")
a(class="nav-link pl-0 text-nowrap" href="/account/")
span(class="font-weight-bold" style="color:black;") #{user.firstName} #{user.lastName}
li(class="nav-item")
a(class="nav-link pl-0" href="/account/profile")
i(class="fa fa-user fa-fw")
span(class="d-none d-md-inline") Benutzerprofil
if user.is_m4lab_idp
li(class="nav-item")
a(class="nav-link pl-0" href="/account/security")
i(class="fa fa-lock fa-fw")
span(class="d-none d-md-inline") Sicherheitseinstellungen
li(class="nav-item")
a(class="nav-link pl-0" href="/account/services")
i(class="fa fa-tasks fa-fw" style="color:black;")
span(class="d-none d-md-inline" style="color:black;") Projekte und Dienste
li(class="nav-item")
a(class="nav-link pl-0" href="/logout" style="color:red;")
i(class="fa fa-sign-out-alt fa-fw")
span(class="d-none d-md-inline") Logout
main(class="col bg-faded py-3 flex-grow-1")
nav(aria-label="breadcrumb")
ol(class="breadcrumb")
li(class="breadcrumb-item")
a(href="/account") Konto
li(class="breadcrumb-item")
a(href="/account/services") Projekte und Dienste
li(class="breadcrumb-item active" aria-current="page") Neue Projektinformation
if flash.success
div.alert.alert-success.alert-dismissible #{flash.success}
a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
if flash.error
div.alert.alert-danger.alert-dismissible.fade.show #{flash.error}
a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
h3(class="pb-2") Neue Projektinformation
div(class="mx-4")
h4(class="pb-1") Schritt 1: Setup
p Bitte füllen Sie alle Felder aus
form(method="POST", encType="multipart/form-data")
div(class='form-group row')
label(for="template", class="col-sm-2") Template
div(class="col-sm-8")
select#templateSelector(name="template", class="form-control")
option(value="generic") generic
option(value="simple_raw") simple_raw
option(value="simple_thesis") simple_thesis
| <span id="templateExample" class="font-italic font-weight-light"><small>See the demo: <a href="https://transfer.hft-stuttgart.de/pages/athanasios.koukofikis/mygeneric/home/" target="_blank">generic</a>, <a href="https://transfer.hft-stuttgart.de/pages/athanasios.koukofikis/myraw/home/" target="_blank">simple_raw</a>, <a href="https://transfer.hft-stuttgart.de/pages/athanasios.koukofikis/mythesis/home/" target="_blank">simple_thesis</a></small></span>
div(class='form-group row')
label(for="name", class="col-sm-2") Name
div(class="col-sm-8")
input#name(name="name", type="text", class="form-control", placeholder="Name", maxlength="75" required)
p(id="nameInfo" class="font-italic font-weight-light") <small>Ihre Webseite wird unter folgender URL veröffentlicht: <strong>https://transfer.hft-stuttgart.de/pages/#{gitlabUsername}/<span id="websiteName"></span></strong></small>
div(class="form-group row")
label(for="description", class="col-sm-2") Beschreibung
div(class="col-sm-8")
textarea#description(name="description", type="text", class="form-control", placeholder="Beschreibung", maxlength="500" required)
div(class="form-group row")
label(for="logo", class="col-sm-2") Projektlogo
div(class="col-sm-8")
input#logo(name="logo", class="form-control-file", type="file" required)
input(type="submit", class="btn btn-primary", value="Senden")
hr
div(class="mx-4", style="color: gray;")
h4(class="pb-1") Schritt 2: Dateneingabe
p Bitte stellen Sie sicher, dass sie Folgendes abgeschlossen haben, bevor Sie Ihre Webseite veröffentlichen:
ol
li index.html
li Anpassen der Standardwerte in <i>settings.js</i>
// jQuery
script(src="https://code.jquery.com/jquery-3.3.1.min.js")
script(src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js", integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1", crossorigin="anonymous")
// jquery-loading-overlay
script(src="https://cdn.jsdelivr.net/npm/gasparesganga-jquery-loading-overlay@2.1.7/dist/loadingoverlay.min.js")
// Bootstrap
script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous")
// M4_LAB
script(src="/js/headfoot.js")
script.
// website URL
function showWebsiteURL() {
if ($("#name").val()) {
$("#nameInfo").show()
let webName = $("#name").val().toLowerCase().replace(/\s/g, '-')
document.getElementById("websiteName").innerText = webName+"/home/"
}
else {
$("#nameInfo").hide()
}
}
$('#name').on('input',function(e){
showWebsiteURL()
})
showWebsiteURL()
$("form").submit(function(){
$.LoadingOverlay("show")
});
\ No newline at end of file
doctype html doctype html
html(lang="de") html(lang="de")
head head
title= "User Profile" title= "Benutzerprofil"
meta(charset="UTF-8") meta(charset="UTF-8")
meta(name="viewport", content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no") meta(name="viewport", content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no")
link(rel="stylesheet", type="text/css", href="/css/bootstrap.min.css") link(rel="stylesheet", type="text/css", href="/css/bootstrap.min.css")
...@@ -16,12 +16,12 @@ html(lang="de") ...@@ -16,12 +16,12 @@ html(lang="de")
ul(class="flex-md-column flex-row navbar-nav w-100 justify-content-between") ul(class="flex-md-column flex-row navbar-nav w-100 justify-content-between")
li(class="nav-item") li(class="nav-item")
a(class="nav-link pl-0 text-nowrap" href="/account/") a(class="nav-link pl-0 text-nowrap" href="/account/")
span(class="font-weight-bold" style="color:black;") #{user.firstname} #{user.lastname} span(class="font-weight-bold" style="color:black;") #{user.firstName} #{user.lastName}
li(class="nav-item") li(class="nav-item")
a(class="nav-link pl-0" href="/account/profile") a(class="nav-link pl-0" href="/account/profile")
i(class="fa fa-user fa-fw" style="color:black;") i(class="fa fa-user fa-fw" style="color:black;")
span(class="d-none d-md-inline" style="color:black;") Benutzerprofil span(class="d-none d-md-inline" style="color:black;") Benutzerprofil
if user.m4lab_idp == 1 if user.is_m4lab_idp
li(class="nav-item") li(class="nav-item")
a(class="nav-link pl-0" href="/account/security") a(class="nav-link pl-0" href="/account/security")
i(class="fa fa-lock fa-fw") i(class="fa fa-lock fa-fw")
...@@ -35,14 +35,20 @@ html(lang="de") ...@@ -35,14 +35,20 @@ html(lang="de")
i(class="fa fa-sign-out-alt fa-fw") i(class="fa fa-sign-out-alt fa-fw")
span(class="d-none d-md-inline") Logout span(class="d-none d-md-inline") Logout
main(class="col bg-faded py-3 flex-grow-1") main(class="col bg-faded py-3 flex-grow-1")
if successes nav(aria-label="breadcrumb")
for success in successes ol(class="breadcrumb")
div.alert.alert-success.alert-dismissible #{ success } li(class="breadcrumb-item")
a(class="close", href="#", data-dismiss="alert", aria-label="close") &times; a(href="/account") Konto
if errors li(class="breadcrumb-item active" aria-current="page") Benutzerprofil
for error, i in errors
div.alert.alert-danger.alert-dismissible.fade.show #{ error } if flash.success
a(class="close", href="#", data-dismiss="alert", aria-label="close") &times; div.alert.alert-success.alert-dismissible #{flash.success}
a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
if flash.error
div.alert.alert-danger.alert-dismissible.fade.show #{flash.error}
a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
h3(class="pb-2") Mein Profil
form#profileForm(method="POST", action="/updateProfile") form#profileForm(method="POST", action="/updateProfile")
div(class="form-row") div(class="form-row")
div(class='form-group col-md-2') div(class='form-group col-md-2')
...@@ -73,14 +79,14 @@ html(lang="de") ...@@ -73,14 +79,14 @@ html(lang="de")
} }
div(class='form-group col-md-2') div(class='form-group col-md-2')
label(for="firstname") Vorname label(for="firstname") Vorname
input#inputFirstname(name="inputFirstname", type="text", class="form-control", placeholder="Vorname", value=user.firstname, maxlength="45" required) input#inputFirstname(name="inputFirstname", type="text", class="form-control", placeholder="Vorname", value=user.firstName, maxlength="45" required)
div(class='form-group col-md-2') div(class='form-group col-md-2')
label(for="lastname") Nachname label(for="lastname") Nachname
input#inputLastname(name="inputLastname", type="text", class="form-control", placeholder="Nachname", value=user.lastname, maxlength="45" required) input#inputLastname(name="inputLastname", type="text", class="form-control", placeholder="Nachname", value=user.lastName, maxlength="45" required)
div(class="form-row") div(class="form-row")
div(class='form-group col-md-8') div(class='form-group col-md-8')
label(for="email") E-mail Adresse label(for="email") E-mail Adresse
input#inputEmail(name="inputEmail", type="email", class="form-control", placeholder="Email", value=email, maxlength="45" required) input#inputEmail(name="inputEmail", type="email", class="form-control", placeholder="Email", value=user.email, maxlength="45" required)
div(class="form-row") div(class="form-row")
div(class='form-group col-md-8') div(class='form-group col-md-8')
label(for="organisation") Unternehmen label(for="organisation") Unternehmen
......
...@@ -21,14 +21,12 @@ html(lang="de") ...@@ -21,14 +21,12 @@ html(lang="de")
div(class="alert alert-info" role="alert") div(class="alert alert-info" role="alert")
| Auf dieser Seite können sich Benutzer, die keinen Account an der HFT haben, registrieren.<br/> | Auf dieser Seite können sich Benutzer, die keinen Account an der HFT haben, registrieren.<br/>
| Um sich mit ihrem HFT-Account anzumelden, klicken Sie <a class="font-weight-bold" href="https://transfer.hft-stuttgart.de/account/">hier</a>. | Um sich mit ihrem HFT-Account anzumelden, klicken Sie <a class="font-weight-bold" href="https://transfer.hft-stuttgart.de/account/">hier</a>.
if successes if flash.success
for success in successes div.alert.alert-success.alert-dismissible #{flash.success}
div.alert.alert-success.alert-dismissible #{ success } a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
a(class="close", href="#", data-dismiss="alert", aria-label="close") &times; if flash.error
if errors div.alert.alert-danger.alert-dismissible.fade.show #{flash.error}
for error, i in errors a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
div.alert.alert-danger.alert-dismissible.fade.show #{ error }
a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
form(method="POST") form(method="POST")
h5(class="pt-2 mb-3 font-weight-bold") Anmeldedaten h5(class="pt-2 mb-3 font-weight-bold") Anmeldedaten
div(class='form-row') div(class='form-row')
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment