Commit e7931881 authored by Rosanny Sihombing's avatar Rosanny Sihombing
Browse files

MLAB-129: add user verification mechanism

parent 3bfcbafc
...@@ -42,14 +42,26 @@ var methods = { ...@@ -42,14 +42,26 @@ var methods = {
throw err throw err
}); });
} }
// COMMIT // MLAB-129: INSERT verification token
dbconn.user.commit(function(err) { let verificationData = {
user_id: newUserId,
token: data.verificationToken
}
dbconn.user.query('INSERT INTO verification SET ?', verificationData, function (err, results, fields) {
if (err) { if (err) {
return dbconn.user.rollback(function() { return dbconn.user.rollback(function() {
throw err throw err
}); });
} }
}); // COMMIT
dbconn.user.commit(function(err) {
if (err) {
return dbconn.user.rollback(function() {
throw err
})
}
})
})
}) })
}); });
}); });
...@@ -57,7 +69,7 @@ var methods = { ...@@ -57,7 +69,7 @@ var methods = {
}) })
}, },
getUserByEmail: function(email, callback) { getUserByEmail: function(email, callback) {
dbconn.user.query('SELECT salutation, title, firstname, lastname, industry, organisation, speciality FROM user WHERE email = "' +email+'"', function (err, rows, fields) { dbconn.user.query('SELECT verificationStatus, salutation, title, firstname, lastname, industry, organisation, speciality FROM user WHERE email = "' +email+'"', function (err, rows, fields) {
if (err) { if (err) {
throw err; throw err;
} }
...@@ -70,7 +82,7 @@ var methods = { ...@@ -70,7 +82,7 @@ var methods = {
}); });
}, },
checkUserEmail: function(email, callback) { checkUserEmail: function(email, callback) {
var 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, fields) {
if (err) { if (err) {
throw err; throw err;
...@@ -84,7 +96,7 @@ var methods = { ...@@ -84,7 +96,7 @@ var methods = {
}); });
}, },
getUserByToken: function(token, callback) { getUserByToken: function(token, callback) {
var 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) {
...@@ -100,42 +112,92 @@ var methods = { ...@@ -100,42 +112,92 @@ var methods = {
} }
); );
}, },
updateUser: function(userData, callback) { updateUserById: function(userData, callback) {
dbconn.user.query('UPDATE user SET ? WHERE email = "' +userData.email+'"', userData, function (err, rows, fields) { dbconn.user.query('UPDATE user SET ? WHERE id = ' +userData.id, userData, function (err, rows, fields) {
if (err) throw err; if (err) throw err
callback(err); callback(err)
}) })
}, },
updateCredential: function(data, callback) { updateCredential: function(data, callback) {
dbconn.user.query('UPDATE credential SET ? WHERE user_id = ' +data.user_id, data, function (err, rows, fields) { dbconn.user.query('UPDATE credential SET ? WHERE user_id = ' +data.user_id, data, function (err, rows, fields) {
if (err) throw err; if (err) throw err
callback(err); callback(err)
}) })
}, },
getUserIdByEmail: function(email, callback) { getUserIdByEmail: function(email, callback) {
var userId let userId
dbconn.user.query('SELECT id FROM user WHERE email = "' +email+'"', function (err, rows, fields) { dbconn.user.query('SELECT id FROM user WHERE email = "' +email+'"', function (err, rows, fields) {
if (err) { if (err) {
throw err; throw err
} }
else { else {
if ( rows.length > 0) { if ( rows.length > 0) {
userId = rows[0].id; userId = rows[0].id
} }
} }
callback(userId, err); callback(userId, err)
}); });
}, },
getUserProjectRole: function(userId, callback) { getUserProjectRole: function(userId, callback) {
dbconn.user.query('SELECT project_id, role_id FROM user_project_role WHERE user_id = "' +userId+'"', function (err, rows, fields) { dbconn.user.query('SELECT project_id, role_id FROM user_project_role WHERE user_id = "' +userId+'"', function (err, rows, fields) {
if (err) throw err; if (err) throw err
callback(rows, err); callback(rows, err)
}); });
}, },
addUserProjectRole: function(data, callback) { addUserProjectRole: function(data, callback) {
dbconn.user.query('INSERT INTO user_project_role SET ?', data, function (err, results, fields){ dbconn.user.query('INSERT INTO user_project_role SET ?', data, function (err, results, fields){
if (err) throw err; if (err) throw err
callback(err); callback(err)
})
},
getVerificationTokenByUserId: function(userId, callback) {
let token
dbconn.user.query('SELECT token FROM verification WHERE user_id = "' +userId+'"', function (err, rows, fields) {
if (err) {
throw err
}
else {
if (rows.length > 0) {
token = rows[0].token
}
}
callback(token, err)
})
},
getUserIdByVerificationToken: function(token, callback) {
let userId
dbconn.user.query('SELECT user_id FROM verification WHERE token = "' +token+'"', function (err, rows, fields) {
if (err) {
throw err
}
else if(rows[0]) {
userId = rows[0].user_id
}
callback(userId, err)
})
},
verifyUserAccount: function(userData, callback) {
dbconn.user.beginTransaction(function(err) { // START TRANSACTION
if (err) { throw err }
// update user status
dbconn.user.query('UPDATE user SET ? WHERE id =' +userData.id, userData, function (err, rows, fields) {
if (err) {
return dbconn.user.rollback(function() { throw err })
}
// delete verification token
dbconn.user.query('DELETE FROM verification WHERE user_id = '+userData.id, function (err, rows, fields) {
if (err) {
return dbconn.user.rollback(function() { throw err })
}
// COMMIT
dbconn.user.commit(function(err) {
if (err) {
return dbconn.user.rollback(function() { throw err })
}
})
})
})
callback(err)
}) })
}, },
// ======================= project db ======================= // ======================= project db =======================
......
...@@ -142,10 +142,18 @@ module.exports = function (app, config, passport, i18n) { ...@@ -142,10 +142,18 @@ module.exports = function (app, config, passport, i18n) {
if (req.isAuthenticated()) { if (req.isAuthenticated()) {
methods.getUserByEmail(req.user.email, function(data, err){ methods.getUserByEmail(req.user.email, function(data, err){
if (!err) { if (!err) {
res.render(lang+'/account/profile', { if (data.verificationStatus == 1) {
user: data, console.log(data)
email: req.user.email res.render(lang+'/account/profile', {
}); user: data,
email: req.user.email
})
}
else {
res.render(lang+'/account/home', {
user: data
});
}
} }
}) })
} else { } else {
...@@ -155,63 +163,74 @@ module.exports = function (app, config, passport, i18n) { ...@@ -155,63 +163,74 @@ module.exports = function (app, config, passport, i18n) {
app.get('/services', function (req, res) { app.get('/services', function (req, res) {
if (req.isAuthenticated()) { if (req.isAuthenticated()) {
async.waterfall([ methods.getUserByEmail(req.user.email, function(data, err){
// get userId by email from userdb if (!err) {
function(done) { if (data.verificationStatus == 1) {
methods.getUserIdByEmail(req.user.email, function(userId, err) { async.waterfall([
if (!err) { // get userId by email from userdb
done(err, userId) 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) { // get user-project-role from userdb
done(err, userProjects) 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) { // get all projects from projectdb
done(err, userProjects, projectsOverview) 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 },
// create JSON object of projects and user status for front-end
var userProjectId = [] // array of user's project_id function(userProjects, projectsOverview, done) {
for (var i = 0; i < userProjects.length; i++) { var allProjects = [] // JSON object
userProjectId.push(userProjects[i].project_id)
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
});
}
])
} }
else {
for (var i = 0; i < projectsOverview.length; i++) { res.render(lang+'/account/home', {
// check if projectId is exist in userProjectId[] user: data
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: req.user,
project: allProjects
});
} }
]) })
} else { } else {
res.redirect('/login'); res.redirect('/login');
} }
...@@ -219,9 +238,21 @@ module.exports = function (app, config, passport, i18n) { ...@@ -219,9 +238,21 @@ module.exports = function (app, config, passport, i18n) {
app.get('/security', function (req, res) { app.get('/security', function (req, res) {
if (req.isAuthenticated()) { if (req.isAuthenticated()) {
res.render(lang+'/account/security', { methods.getUserByEmail(req.user.email, function(data, err){
user: req.user // useful for view engine, useless for HTML if (!err) {
}); if (data.verificationStatus == 1) {
console.log(data)
res.render(lang+'/account/security', {
user: data
})
}
else {
res.render(lang+'/account/home', {
user: data
});
}
}
})
} else { } else {
res.redirect('/login'); res.redirect('/login');
} }
...@@ -474,16 +505,11 @@ module.exports = function (app, config, passport, i18n) { ...@@ -474,16 +505,11 @@ module.exports = function (app, config, passport, i18n) {
}); });
// todo: user registration with captcha // ============= 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')
}) })
app.post('/registration', function(req, res) { app.post('/registration', function(req, res) {
// TODO:
// create gitlab account?
// send email to activate profile?
// user data // user data
var curDate = new Date() var curDate = new Date()
var userData = { var userData = {
...@@ -497,27 +523,132 @@ module.exports = function (app, config, passport, i18n) { ...@@ -497,27 +523,132 @@ module.exports = function (app, config, passport, i18n) {
speciality: req.body.inputSpeciality, speciality: req.body.inputSpeciality,
createdDate: curDate.toISOString().slice(0,10) createdDate: curDate.toISOString().slice(0,10)
} }
// encrypt password
bcrypt.genSalt(saltRounds, function(err, salt) { let token
bcrypt.hash(req.body.inputPassword, salt, function(err, hash) { async.waterfall([
// create account function(done) {
var newAccount = { crypto.randomBytes(20, function(err, buf) {
profile: userData, token = buf.toString('hex');
password: hash 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){ methods.registerNewUser(newAccount, function(err){
if (err) { if (err) {
//req.flash('error', "Failed")
req.flash('error', "Fehlgeschlagen") req.flash('error', "Fehlgeschlagen")
} }
else { else {
//req.flash('success', 'Your account has been created. Please log in.') // send email
req.flash('success', 'Ihr Benutzerkonto wurde angelegt. Bitte melden Sie sich an.') 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
mailer.options.to = req.body.inputEmail;
mailer.options.subject = emailSubject;
mailer.options.text = emailContent;
mailer.transport.sendMail(mailer.options, function(err) {
if (err) {
console.log('cannot send email')
throw err
}
})
// user feedback
req.flash('success', '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.\r\n \r\n'+
'Ohne Bestätigung Ihres Kontos müssen wir Ihr Konto leider nach 7 Tagen löschen.')
} }
res.redirect('/account/registration'); res.redirect('/account/registration')
}) })
}); }
}); ])
})
// ============= USER VERIFICATION ================================
app.get("/verifyAccount", function(req, res){
methods.getUserIdByVerificationToken(req.query.token, function(userId, err){
console.log(err)
console.log(userId)
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 {
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
mailer.options.to = emailAddress;
mailer.options.subject = emailSubject;
mailer.options.text = 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) { app.get('/email/:email', function(req, res) {
......
...@@ -7,35 +7,44 @@ html(lang="de") ...@@ -7,35 +7,44 @@ html(lang="de")
link(rel="stylesheet", type="text/css", href="https://transfer.hft-stuttgart.de/css/bootstrap/bootstrap.css") link(rel="stylesheet", type="text/css", href="https://transfer.hft-stuttgart.de/css/bootstrap/bootstrap.css")
link(rel="stylesheet", href="https://use.fontawesome.com/releases/v5.8.2/css/all.css", integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay", crossorigin="anonymous") link(rel="stylesheet", href="https://use.fontawesome.com/releases/v5.8.2/css/all.css", integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay", crossorigin="anonymous")
body body
div(class="container-fluid") div(class="container")
div(class="row min-vh-100 flex-column flex-md-row") if user.verificationStatus == 0
aside(class="col-12 col-md-2 p-0 flex-shrink-1") div.alert.alert-warning.alert-dismissible
nav(class="navbar navbar-expand flex-md-column flex-row align-items-start py-2") | Willkommen im Benutzerkonto-Bereich des HFT Transferportals
div(class="collapse navbar-collapse") | <br/><br/>
ul(class="flex-md-column flex-row navbar-nav w-100 justify-content-between") | Wir haben Ihnen eine E-Mail an Ihre verwendete Adresse gesendet. Diese enthält einen Link zur Bestätigung Ihres Accounts.
li(class="nav-item") | Wenn Sie die Mail nicht in ihrem Postfach vorfinden, prüfen Sie bitte auch Ihren Spam-Ordner.
a(class="nav-link pl-0 text-nowrap" href="#") | <br >Falls Sie keine E-Mail von uns erhalten haben, können Sie <a href="javascript:void(0);" onclick="verify();">diese hier</a> erneut anfordern.
span(class="font-weight-bold" style="color:black;") #{user.firstname} #{user.lastname} div(class="spinner-border text-secondary", role="status", style="display: none")
li(class="nav-item") else
a(class="nav-link pl-0" href="/account/profile") div(class="row min-vh-100 flex-column flex-md-row")
i(class="fa fa-user fa-fw") aside(class="col-12 col-md-3 p-0 flex-shrink-1")
span(class="d-none d-md-inline") Benutzerprofil nav(class="navbar navbar-expand flex-md-column flex-row align-items-start py-2")
li(class="nav-item") div(class="collapse navbar-collapse")
a(class="nav-link pl-0" href="/account/security") ul(class="flex-md-column flex-row navbar-nav w-100 justify-content-between")
i(class="fa fa-lock fa-fw") li(class="nav-item")
span(class="d-none d-md-inline") Sicherheitseinstellungen a(class="nav-link pl-0 text-nowrap" href="#")
li(class="nav-item") span(class="font-weight-bold" style="color:black;") #{user.firstname} #{user.lastname}
a(class="nav-link pl-0" href="/account/services") li(class="nav-item")
i(class="fa fa-tasks fa-fw") a(class="nav-link pl-0" href="/profile")
span(class="d-none d-md-inline") Projekte und Dienste i(class="fa fa-user fa-fw")
li(class="nav-item") span(class="d-none d-md-inline") Benutzerprofil
a(class="nav-link pl-0" href="/logout") li(class="nav-item")
i(class="fa fa-sign-out-alt fa-fw") a(class="nav-link pl-0" href="/security")
span(class="d-none d-md-inline") Logout i(class="fa fa-lock fa-fw")
main(class="col bg-faded py-3 flex-grow-1") span(class="d-none d-md-inline") Sicherheitseinstellungen
p Willkommen im Benutzerkonto-Bereich des HFT Transferportals li(class="nav-item")
p In diesem Bereich können Sie Ihr Benutzerkonto pflegen.<br/> Dazu finden Sie auf der linken Seite verschiedene Menüs. a(class="nav-link pl-0" href="/services")
p Bei Rückfragen kontaktieren Sie uns bitte unter: <a href="mailto:support-transfer@hft-stuttgart.de">support-transfer@hft-stuttgart.de</a> i(class="fa fa-tasks fa-fw")
span(class="d-none d-md-inline") 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")
p Willkommen im Benutzerkonto-Bereich des HFT Transferportals
p In diesem Bereich können Sie Ihr Benutzerkonto pflegen.<br/> Dazu finden Sie auf der linken Seite verschiedene Menüs.
p Bei Rückfragen kontaktieren Sie uns bitte unter: <a href="mailto:support-transfer@hft-stuttgart.de">support-transfer@hft-stuttgart.de</a>
// jQuery // jQuery
script(src="https://code.jquery.com/jquery-3.3.1.min.js") script(src="https://code.jquery.com/jquery-3.3.1.min.js")
...@@ -43,4 +52,25 @@ html(lang="de") ...@@ -43,4 +52,25 @@ html(lang="de")
// Bootstrap // Bootstrap
script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous") script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous")
// M4_LAB // M4_LAB
script(src="/js/headfoot.js") script(src="https://m4lab.hft-stuttgart.de/js/headfoot.js")
\ No newline at end of file script.
// call verifyAccount
function verify() {
$(".spinner-border").show()
$.get( "/resendVerificationEmail", function( data ) {
console.log(data)
if (data) {
alert( "Email sent!" )
}
else {
alert("Please contact support-transfer@hft-stuttgart.de to verify your account.")
}
})
.fail(function() {
alert( "Something went wrong. Please try again." ) // todo: to DE
})
.always(function() {
$(".spinner-border").hide()
})
}
\ No newline at end of file
...@@ -7,29 +7,29 @@ html(lang="de") ...@@ -7,29 +7,29 @@ html(lang="de")
link(rel="stylesheet", type="text/css", href="https://transfer.hft-stuttgart.de/css/bootstrap/bootstrap.css") link(rel="stylesheet", type="text/css", href="https://transfer.hft-stuttgart.de/css/bootstrap/bootstrap.css")
link(rel="stylesheet", href="https://use.fontawesome.com/releases/v5.8.2/css/all.css", integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay", crossorigin="anonymous") link(rel="stylesheet", href="https://use.fontawesome.com/releases/v5.8.2/css/all.css", integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay", crossorigin="anonymous")
body body
div(class="container-fluid") div(class="container")
div(class="row min-vh-100 flex-column flex-md-row") div(class="row min-vh-100 flex-column flex-md-row")
aside(class="col-12 col-md-2 p-0 flex-shrink-1") 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") nav(class="navbar navbar-expand flex-md-column flex-row align-items-start py-2")
div(class="collapse navbar-collapse") div(class="collapse navbar-collapse")
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="/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
li(class="nav-item") li(class="nav-item")
a(class="nav-link pl-0" href="/account/security") a(class="nav-link pl-0" href="/security")
i(class="fa fa-lock fa-fw") i(class="fa fa-lock fa-fw")
span(class="d-none d-md-inline") Sicherheitseinstellungen span(class="d-none d-md-inline") Sicherheitseinstellungen
li(class="nav-item") li(class="nav-item")
a(class="nav-link pl-0" href="/account/services") a(class="nav-link pl-0" href="/services")
i(class="fa fa-tasks fa-fw") i(class="fa fa-tasks fa-fw")
span(class="d-none d-md-inline") Projekte und Dienste span(class="d-none d-md-inline") Projekte und Dienste
li(class="nav-item") li(class="nav-item")
a(class="nav-link pl-0" href="/logout") a(class="nav-link pl-0" href="/logout" style="color:red;")
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")
...@@ -45,7 +45,7 @@ html(lang="de") ...@@ -45,7 +45,7 @@ html(lang="de")
div(class="form-row") div(class="form-row")
div(class='form-group col-md-2') div(class='form-group col-md-2')
label(for="title") Anrede label(for="title") Anrede
select#inputSalutation(name="inputSalutation", class="form-control", , value=user.salutation) select#inputSalutation(name="inputSalutation", class="form-control", value=user.salutation)
option(value="") - Anrede - option(value="") - Anrede -
option(value="Herr") Herr option(value="Herr") Herr
option(value="Frau") Frau option(value="Frau") Frau
...@@ -99,4 +99,4 @@ html(lang="de") ...@@ -99,4 +99,4 @@ html(lang="de")
// Bootstrap // Bootstrap
script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous") script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous")
// M4_LAB // M4_LAB
script(src="/js/headfoot.js") script(src="https://m4lab.hft-stuttgart.de/js/headfoot.js")
\ No newline at end of file \ No newline at end of file
...@@ -7,26 +7,6 @@ html(lang="de") ...@@ -7,26 +7,6 @@ html(lang="de")
link(rel="stylesheet", type="text/css", href="https://transfer.hft-stuttgart.de/css/bootstrap/bootstrap.css") link(rel="stylesheet", type="text/css", href="https://transfer.hft-stuttgart.de/css/bootstrap/bootstrap.css")
link(rel="stylesheet", href="https://use.fontawesome.com/releases/v5.8.2/css/all.css", integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay", crossorigin="anonymous") link(rel="stylesheet", href="https://use.fontawesome.com/releases/v5.8.2/css/all.css", integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay", crossorigin="anonymous")
style. style.
.collapse {
display: none;
}
.collapse.in {
display: block;
}
.collapsing {
position: relative;
height: 0;
overflow: hidden;
-webkit-transition-timing-function: ease;
-o-transition-timing-function: ease;
transition-timing-function: ease;
-webkit-transition-duration: .35s;
-o-transition-duration: .35s;
transition-duration: .35s;
-webkit-transition-property: height,visibility;
-o-transition-property: height,visibility;
transition-property: height,visibility;
}
.warning { .warning {
color: red; color: red;
font-size: 11px; font-size: 11px;
...@@ -94,4 +74,4 @@ html(lang="de") ...@@ -94,4 +74,4 @@ html(lang="de")
// M4_LAB // M4_LAB
script(src="/js/generalFunction.js") script(src="/js/generalFunction.js")
script(src="/js/registration.js") script(src="/js/registration.js")
script(src="/js/headfoot.js") script(src="https://m4lab.hft-stuttgart.de/js/headfoot.js")
\ No newline at end of file \ No newline at end of file
...@@ -11,29 +11,29 @@ html(lang="de") ...@@ -11,29 +11,29 @@ html(lang="de")
font-size: 11px; font-size: 11px;
} }
body body
div(class="container-fluid") div(class="container")
div(class="row min-vh-100 flex-column flex-md-row") div(class="row min-vh-100 flex-column flex-md-row")
aside(class="col-12 col-md-2 p-0 flex-shrink-1") 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") nav(class="navbar navbar-expand flex-md-column flex-row align-items-start py-2")
div(class="collapse navbar-collapse") div(class="collapse navbar-collapse")
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="/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
li(class="nav-item") li(class="nav-item")
a(class="nav-link pl-0" href="/account/security") a(class="nav-link pl-0" href="/security")
i(class="fa fa-lock fa-fw" style="color:black;") i(class="fa fa-lock fa-fw" style="color:black;")
span(class="d-none d-md-inline" style="color:black;") Sicherheitseinstellungen span(class="d-none d-md-inline" style="color:black;") Sicherheitseinstellungen
li(class="nav-item") li(class="nav-item")
a(class="nav-link pl-0" href="/account/services") a(class="nav-link pl-0" href="/services")
i(class="fa fa-tasks fa-fw") i(class="fa fa-tasks fa-fw")
span(class="d-none d-md-inline") Projekte und Dienste span(class="d-none d-md-inline") Projekte und Dienste
li(class="nav-item") li(class="nav-item")
a(class="nav-link pl-0" href="/logout") a(class="nav-link pl-0" href="/logout" style="color:red;")
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")
...@@ -64,7 +64,7 @@ html(lang="de") ...@@ -64,7 +64,7 @@ html(lang="de")
span#message span#message
div(class="invalid-feedback") Bitte füllen Sie dieses Feld aus. div(class="invalid-feedback") Bitte füllen Sie dieses Feld aus.
input#updateBtn(type="submit", class="btn btn-primary", value="Passwort ändern" disabled) input#updateBtn(type="submit", class="btn btn-primary", value="Passwort ändern" disabled)
// jQuery // jQuery
script(src="https://code.jquery.com/jquery-3.3.1.min.js") 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") script(src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js", integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1", crossorigin="anonymous")
...@@ -73,7 +73,7 @@ html(lang="de") ...@@ -73,7 +73,7 @@ html(lang="de")
// M4_LAB // M4_LAB
script(src="/js/security.js") script(src="/js/security.js")
script(src="/js/generalFunction.js") script(src="/js/generalFunction.js")
script(src="/js/headfoot.js") script(src="https://m4lab.hft-stuttgart.de/js/headfoot.js")
script. script.
// check input fields // check input fields
'use strict'; 'use strict';
......
...@@ -7,29 +7,29 @@ html(lang="de") ...@@ -7,29 +7,29 @@ html(lang="de")
link(rel="stylesheet", type="text/css", href="https://transfer.hft-stuttgart.de/css/bootstrap/bootstrap.css") link(rel="stylesheet", type="text/css", href="https://transfer.hft-stuttgart.de/css/bootstrap/bootstrap.css")
link(rel="stylesheet", href="https://use.fontawesome.com/releases/v5.8.2/css/all.css", integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay", crossorigin="anonymous") link(rel="stylesheet", href="https://use.fontawesome.com/releases/v5.8.2/css/all.css", integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay", crossorigin="anonymous")
body body
div(class="container-fluid") div(class="container")
div(class="row min-vh-100 flex-column flex-md-row") div(class="row min-vh-100 flex-column flex-md-row")
aside(class="col-12 col-md-2 p-0 flex-shrink-1") 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") nav(class="navbar navbar-expand flex-md-column flex-row align-items-start py-2")
div(class="collapse navbar-collapse") div(class="collapse navbar-collapse")
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="/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
li(class="nav-item") li(class="nav-item")
a(class="nav-link pl-0" href="/account/security") a(class="nav-link pl-0" href="/security")
i(class="fa fa-lock fa-fw") i(class="fa fa-lock fa-fw")
span(class="d-none d-md-inline") Sicherheitseinstellungen span(class="d-none d-md-inline") Sicherheitseinstellungen
li(class="nav-item") li(class="nav-item")
a(class="nav-link pl-0" href="/account/services") a(class="nav-link pl-0" href="/services")
i(class="fa fa-tasks fa-fw" style="color:black;") i(class="fa fa-tasks fa-fw" style="color:black;")
span(class="d-none d-md-inline" style="color:black;") Projekte und Dienste span(class="d-none d-md-inline" style="color:black;") Projekte und Dienste
li(class="nav-item") li(class="nav-item")
a(class="nav-link pl-0" href="/logout") a(class="nav-link pl-0" href="/logout" style="color:red;")
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")
...@@ -41,4 +41,4 @@ html(lang="de") ...@@ -41,4 +41,4 @@ html(lang="de")
// Bootstrap // Bootstrap
script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous") script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous")
// M4_LAB // M4_LAB
script(src="/js/headfoot.js") script(src="https://m4lab.hft-stuttgart.de/js/headfoot.js")
\ No newline at end of file \ No newline at end of file
doctype html
html(lang="de")
head
title= "User Verification"
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="https://transfer.hft-stuttgart.de/css/bootstrap/bootstrap.css")
style.
.container {
height: 400px;
position: relative;
}
.center {
margin: 0;
position: absolute;
top: 50%;
left: 50%;
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
body
div(class="container")
div(class="center", align="center")
a(href="https://m4lab.hft-stuttgart.de")
img(src="https://transfer.hft-stuttgart.de/images/demo/m4lab_logo.jpg", class="img-responsive center-block", width="185", height="192")
br
br
if status == true
p(class="h5") Ihr Benutzerkonto wurde bestätigt. Bitte <a href="https://m4lab.hft-stuttgart.de/account/">melden Sie sich an</a>.
else if status == false
p(class="h5") Ihr Benutzerkonto konnte nicht bestätigt werden, bitte versuchen Sie es erneut.
else
p(class="h5") Ihr Benutzerkonto wude nicht gefunden.
// Bootstrap
script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous")
\ No newline at end of file
Markdown is supported
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