Commit e091713c authored by Wolfgang Knopki's avatar Wolfgang Knopki
Browse files

Merge branch 'MLAB-129' into 'testing'

MLAB 129

See merge request !34
parents ece9da9c 2560776a
Pipeline #743 passed with stage
in 30 seconds
...@@ -16,7 +16,7 @@ i18n.configure({ ...@@ -16,7 +16,7 @@ i18n.configure({
directory: './locales' directory: './locales'
}); });
var env = process.env.NODE_ENV || 'development'; var env = process.env.NODE_ENV || 'testing';
const config = require('./config/config')[env]; const config = require('./config/config')[env];
var app = express(); var app = express();
......
...@@ -2,14 +2,48 @@ module.exports = { ...@@ -2,14 +2,48 @@ module.exports = {
development: { development: {
app: { app: {
name: 'User Account Management', name: 'User Account Management',
port: process.env.PORT || 9989 port: process.env.PORT || 9989,
host: 'http://localhost:9989'
},
passport: {
strategy: 'saml',
saml: {
path: process.env.SAML_PATH || '/saml/SSO',
entryPoint: process.env.SAML_ENTRY_POINT || 'https://m4lab.hft-stuttgart.de/idp/saml2/idp/SSOService.php',
issuer: 'sp-account.m4lab.hft-stuttgart.de', //local metadata
logoutUrl: 'https://m4lab.hft-stuttgart.de/idp/saml2/idp/SingleLogoutService.php'
}
},
database: {
host: 'localhost', // DB host
user: 'DBManager', // DB username
password: 'Stuttgart2019', // DB password
port: 3306, // MySQL port
dbUser: 'userdb', // User DB
host_project: 'localhost', // DB host project db
dbProject: 'projectDB' // Project DB
},
mailer: {
host: 'mail.hft-stuttgart.de', // hostname
secureConnection: false, // TLS requires secureConnection to be false
port: 587, // port for secure SMTP
authUser: 'ad\\support-transfer',
authPass: '6laumri2',
tlsCiphers: 'SSLv3',
from: 'support-transfer@hft-stuttgart.de',
}
},
testing: {
app: {
name: 'User Account Management',
port: process.env.PORT || 9989,
host: 'https://m4lab.hft-stuttgart.de/account'
}, },
passport: { passport: {
strategy: 'saml', strategy: 'saml',
saml: { saml: {
path: process.env.SAML_PATH || '/saml/SSO', path: process.env.SAML_PATH || '/saml/SSO',
entryPoint: process.env.SAML_ENTRY_POINT || 'https://m4lab.hft-stuttgart.de/idp/saml2/idp/SSOService.php', entryPoint: process.env.SAML_ENTRY_POINT || 'https://m4lab.hft-stuttgart.de/idp/saml2/idp/SSOService.php',
//issuer: 'sp-account.m4lab.hft-stuttgart.de', //local metadata
issuer: 'sp-account-testing.m4lab.hft-stuttgart.de', //testing metadata issuer: 'sp-account-testing.m4lab.hft-stuttgart.de', //testing metadata
//issuer: 'sp-account-prod.m4lab.hft-stuttgart.de', //production metadata //issuer: 'sp-account-prod.m4lab.hft-stuttgart.de', //production metadata
logoutUrl: 'https://m4lab.hft-stuttgart.de/idp/saml2/idp/SingleLogoutService.php' logoutUrl: 'https://m4lab.hft-stuttgart.de/idp/saml2/idp/SingleLogoutService.php'
...@@ -22,7 +56,6 @@ module.exports = { ...@@ -22,7 +56,6 @@ module.exports = {
port: 3306, // MySQL port port: 3306, // MySQL port
dbUser: 'userdb', // User DB dbUser: 'userdb', // User DB
host_project: 'm4lab.hft-stuttgart.de', // DB host project db host_project: 'm4lab.hft-stuttgart.de', // DB host project db
//host_project: 'localhost', // local
dbProject: 'projectDB' // Project DB dbProject: 'projectDB' // Project DB
}, },
mailer: { mailer: {
......
const mysql = require('mysql') const mysql = require('mysql')
var env = process.env.NODE_ENV || 'development'; var env = process.env.NODE_ENV || 'testing';
const config = require('../config/config')[env] const config = require('../config/config')[env]
// ==== USER ACOOUNT DB CONNECTION ==== // ==== USER ACOOUNT DB CONNECTION ====
......
const nodemailer = require('nodemailer') const nodemailer = require('nodemailer')
var env = process.env.NODE_ENV || 'development'; var env = process.env.NODE_ENV || 'testing';
const config = require('../config/config')[env] const config = require('../config/config')[env]
var smtpTransport = nodemailer.createTransport({ var smtpTransport = nodemailer.createTransport({
......
...@@ -37,6 +37,17 @@ var methods = { ...@@ -37,6 +37,17 @@ var methods = {
user_id: newUserId user_id: newUserId
} }
dbconn.user.query('INSERT INTO user_project_role SET ?', projectRoleData, function (err, results, fields) { dbconn.user.query('INSERT INTO user_project_role SET ?', projectRoleData, function (err, results, fields) {
if (err) {
return dbconn.user.rollback(function() {
throw err
});
}
// MLAB-129: INSERT verification token
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
...@@ -47,9 +58,10 @@ var methods = { ...@@ -47,9 +58,10 @@ var methods = {
if (err) { if (err) {
return dbconn.user.rollback(function() { return dbconn.user.rollback(function() {
throw err throw err
}); })
} }
}); })
})
}) })
}); });
}); });
...@@ -57,7 +69,20 @@ var methods = { ...@@ -57,7 +69,20 @@ 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) {
throw err;
}
else {
if ( rows.length > 0) {
user = rows[0];
}
}
callback(user, err);
});
},
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) {
if (err) { if (err) {
throw err; throw err;
} }
...@@ -70,7 +95,7 @@ var methods = { ...@@ -70,7 +95,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 +109,7 @@ var methods = { ...@@ -84,7 +109,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 +125,92 @@ var methods = { ...@@ -100,42 +125,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,11 +142,19 @@ module.exports = function (app, config, passport, i18n) { ...@@ -142,11 +142,19 @@ 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) {
if (data.verificationStatus == 1) {
console.log(data)
res.render(lang+'/account/profile', { res.render(lang+'/account/profile', {
user: data, user: data,
email: req.user.email email: req.user.email
})
}
else {
res.render(lang+'/account/home', {
user: data
}); });
} }
}
}) })
} else { } else {
res.redirect('/login'); res.redirect('/login');
...@@ -155,6 +163,9 @@ module.exports = function (app, config, passport, i18n) { ...@@ -155,6 +163,9 @@ 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()) {
methods.getUserByEmail(req.user.email, function(data, err){
if (!err) {
if (data.verificationStatus == 1) {
async.waterfall([ async.waterfall([
// get userId by email from userdb // get userId by email from userdb
function(done) { function(done) {
...@@ -207,11 +218,19 @@ module.exports = function (app, config, passport, i18n) { ...@@ -207,11 +218,19 @@ module.exports = function (app, config, passport, i18n) {
// render the page // render the page
res.render(lang+'/account/services', { res.render(lang+'/account/services', {
user: req.user, user: data,
project: allProjects project: allProjects
}); });
} }
]) ])
}
else {
res.render(lang+'/account/home', {
user: data
});
}
}
})
} 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()) {
methods.getUserByEmail(req.user.email, function(data, err){
if (!err) {
if (data.verificationStatus == 1) {
console.log(data)
res.render(lang+'/account/security', { res.render(lang+'/account/security', {
user: req.user // useful for view engine, useless for HTML 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,156 @@ module.exports = function (app, config, passport, i18n) { ...@@ -497,27 +523,156 @@ 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)
} }
let token
async.waterfall([
function(done) {
crypto.randomBytes(20, function(err, buf) {
token = buf.toString('hex');
done(err, token);
});
},
// encrypt password // encrypt password
function(token, done) {
bcrypt.genSalt(saltRounds, function(err, salt) { bcrypt.genSalt(saltRounds, function(err, salt) {
bcrypt.hash(req.body.inputPassword, salt, function(err, hash) { bcrypt.hash(req.body.inputPassword, salt, function(err, hash) {
// create account
var newAccount = { var newAccount = {
profile: userData, profile: userData,
password: hash 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.\n"+
"Um Ihre Anmeldung zu bestätigen, klicken Sie bitte diesen Link: "+config.app.host+"/verifyAccount?token="+token+"\n"+
"Ohne Bestätigung Ihres Kontos müssen wir Ihr Konto leider nach 7 Tagen löschen.\n\n"+
"Sollten Sie sich selbst nicht mit Ihren Daten am Transferportal registriert haben, ignorieren Sie diese E-Mail bitte.\n\n"+mailSignature
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
} }
res.redirect('/account/registration');
}) })
// user feedback
req.flash('success', 'Vielen Dank für Ihre Registrierung!'+'\r\n\r\n'+
'Wir haben Ihnen eine E-Mail an Ihre verwendete Adresse gesendet. Diese enthält einen Link zur Bestätigung Ihres Accounts.'+'\r\n'+
'Wenn Sie die Mail nicht in ihrem Postfach vorfinden, prüfen Sie bitte auch Ihren Spam-Ordner.')
}
res.redirect('/account/registration')
})
}
])
})
// ============= USER VERIFICATION ================================
app.get("/verifyAccount", function(req, res){
console.log(req.query)
methods.getUserIdByVerificationToken(req.query.token, function(userId, err){
if (userId) {
let userData = {
id: userId,
verificationStatus: 1
}
methods.verifyUserAccount(userData, function(err){
if (err) {
console.log("Error: "+err)
res.render(lang+'/account/verification', {
status: false
});
}
else {
// send welcome email after successful account verification
methods.getUserById(userId, function(data, err){
if (err) {
console.log("Error: "+err)
}
else {
// send email
var emailSubject = "Herzlich willkommen"
var emailContent = "Lieber Nutzer,\n\n"+
"herzlich willkommen beim Transferportal der HFT Stuttgart!\n"+
"Sie können nun alle Dienste des Portals nutzen.\n\n"+mailSignature
mailer.options.to = data.email;
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.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,9 +7,18 @@ html(lang="de") ...@@ -7,9 +7,18 @@ 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")
if user.verificationStatus == 0
div.alert.alert-warning.alert-dismissible
| Willkommen im Benutzerkonto-Bereich des HFT Transferportals
| <br/><br/>
| Wir haben Ihnen eine E-Mail an Ihre verwendete Adresse gesendet. Diese enthält einen Link zur Bestätigung Ihres Accounts.
| Wenn Sie die Mail nicht in ihrem Postfach vorfinden, prüfen Sie bitte auch Ihren Spam-Ordner.
| <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.
div(class="spinner-border text-secondary", role="status", style="display: none")
else
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")
...@@ -17,19 +26,19 @@ html(lang="de") ...@@ -17,19 +26,19 @@ html(lang="de")
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") 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")
...@@ -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")
...@@ -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
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