Commit 7bbf602d authored by Wolfgang Knopki's avatar Wolfgang Knopki
Browse files

merged devel

parents 3d24af93 423eb5c0
Pipeline #521 passed with stage
in 9 seconds
...@@ -8,6 +8,7 @@ const bodyParser = require('body-parser'); ...@@ -8,6 +8,7 @@ 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');
const i18n = require('i18n'); // internationalization
var env = process.env.NODE_ENV || 'development'; var env = process.env.NODE_ENV || 'development';
const config = require('./config/config')[env]; const config = require('./config/config')[env];
...@@ -47,10 +48,17 @@ app.use(function(req, res, next) { ...@@ -47,10 +48,17 @@ app.use(function(req, res, next) {
next(); next();
}); });
require('./routes/routes')(app, config, passport); // internationalization (i18n)
i18n.configure({
locales:['de', 'en'],
directory: './locales'
});
app.use(i18n.init);
require('./routes/routes')(app, config, passport, i18n);
//require('./routes/dbconn')(app, config); //require('./routes/dbconn')(app, config);
require('./routes/api')(app, config, passport); require('./routes/api')(app, config, passport);
app.listen(app.get('port'), function () { app.listen(app.get('port'), function () {
console.log('Express server listening on port ' + app.get('port')); console.log('Express server listening on port ' + app.get('port'));
}); });
\ No newline at end of file
// add `salutation` column and alter `title` to be not mandatory
ALTER TABLE `userdb`.`user`
ADD COLUMN `salutation` VARCHAR(45) NULL DEFAULT NULL AFTER `email`,
CHANGE COLUMN `title` `title` VARCHAR(45) NULL DEFAULT NULL ;
\ No newline at end of file
{
"Hello World": "Hallo Welt",
"Hello": "Hallo"
}
\ No newline at end of file
{
"Hello World": "Hello World",
"Hello": "Hello",
}
\ No newline at end of file
...@@ -748,6 +748,19 @@ ...@@ -748,6 +748,19 @@
} }
} }
}, },
"i18n": {
"version": "0.8.5",
"resolved": "https://registry.npmjs.org/i18n/-/i18n-0.8.5.tgz",
"integrity": "sha512-6UgLbhJGgn4XFeuZc/dDdrrri0ij24EK4hxv4Pbi5hloYAZ1B2+0eQchEryBFezLKYOHhVGV/5+H4i0oxng94w==",
"requires": {
"debug": "*",
"make-plural": "^6.0.1",
"math-interval-parser": "^2.0.1",
"messageformat": "^2.3.0",
"mustache": "*",
"sprintf-js": "^1.1.2"
}
},
"iconv-lite": { "iconv-lite": {
"version": "0.4.24", "version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
...@@ -982,6 +995,16 @@ ...@@ -982,6 +995,16 @@
"pify": "^3.0.0" "pify": "^3.0.0"
} }
}, },
"make-plural": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/make-plural/-/make-plural-6.0.1.tgz",
"integrity": "sha512-h0uBNi4tpDkiWUyYKrJNj8Kif6q3Ba5zp/8jnfPy3pQE+4XcTj6h3eZM5SYVUyDNX9Zk69Isr/dx0I+78aJUaQ=="
},
"math-interval-parser": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/math-interval-parser/-/math-interval-parser-2.0.1.tgz",
"integrity": "sha512-VmlAmb0UJwlvMyx8iPhXUDnVW1F9IrGEd9CIOmv+XL8AErCUUuozoDMrgImvnYt2A+53qVX/tPW6YJurMKYsvA=="
},
"media-typer": { "media-typer": {
"version": "0.3.0", "version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
...@@ -992,6 +1015,36 @@ ...@@ -992,6 +1015,36 @@
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
}, },
"messageformat": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/messageformat/-/messageformat-2.3.0.tgz",
"integrity": "sha512-uTzvsv0lTeQxYI2y1NPa1lItL5VRI8Gb93Y2K2ue5gBPyrbJxfDi/EYWxh2PKv5yO42AJeeqblS9MJSh/IEk4w==",
"requires": {
"make-plural": "^4.3.0",
"messageformat-formatters": "^2.0.1",
"messageformat-parser": "^4.1.2"
},
"dependencies": {
"make-plural": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/make-plural/-/make-plural-4.3.0.tgz",
"integrity": "sha512-xTYd4JVHpSCW+aqDof6w/MebaMVNTVYBZhbB/vi513xXdiPT92JMVCo0Jq8W2UZnzYRFeVbQiQ+I25l13JuKvA==",
"requires": {
"minimist": "^1.2.0"
}
}
}
},
"messageformat-formatters": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/messageformat-formatters/-/messageformat-formatters-2.0.1.tgz",
"integrity": "sha512-E/lQRXhtHwGuiQjI7qxkLp8AHbMD5r2217XNe/SREbBlSawe0lOqsFb7rflZJmlQFSULNLIqlcjjsCPlB3m3Mg=="
},
"messageformat-parser": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/messageformat-parser/-/messageformat-parser-4.1.2.tgz",
"integrity": "sha512-7dWuifeyldz7vhEuL96Kwq1fhZXBW+TUfbnHN4UCrCxoXQTYjHnR78eI66Gk9LaLLsAvzPNVJBaa66DRfFNaiA=="
},
"methods": { "methods": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
...@@ -1045,6 +1098,11 @@ ...@@ -1045,6 +1098,11 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}, },
"mustache": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/mustache/-/mustache-4.0.0.tgz",
"integrity": "sha512-FJgjyX/IVkbXBXYUwH+OYwQKqWpFPLaLVESd70yHjSDunwzV2hZOoTBvPf4KLoxesUzzyfTH6F784Uqd7Wm5yA=="
},
"mysql": { "mysql": {
"version": "2.17.1", "version": "2.17.1",
"resolved": "https://registry.npmjs.org/mysql/-/mysql-2.17.1.tgz", "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.17.1.tgz",
...@@ -1686,6 +1744,11 @@ ...@@ -1686,6 +1744,11 @@
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
}, },
"sprintf-js": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
"integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug=="
},
"sqlstring": { "sqlstring": {
"version": "2.3.1", "version": "2.3.1",
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
......
...@@ -22,7 +22,8 @@ $('#inputPassword').on('keyup', function () { ...@@ -22,7 +22,8 @@ $('#inputPassword').on('keyup', function () {
isPasswordValid = checkPasswordReq($('#inputPassword').val()) isPasswordValid = checkPasswordReq($('#inputPassword').val())
$('#passwordWarning').empty(); $('#passwordWarning').empty();
if (!isPasswordValid) { if (!isPasswordValid) {
$('#passwordWarning').html('Must be at least 8 characters') //$('#passwordWarning').html('Must be at least 8 characters')
$('#passwordWarning').html('Das Passwort muss mindestens 8 Zeichen haben')
} }
switchSubmitButton() switchSubmitButton()
}); });
......
...@@ -6,15 +6,18 @@ $('#inputNewPwd, #inputConfirm').on('keyup', function () { ...@@ -6,15 +6,18 @@ $('#inputNewPwd, #inputConfirm').on('keyup', function () {
isBest = checkPasswordReq($('#inputNewPwd').val()) isBest = checkPasswordReq($('#inputNewPwd').val())
$('#recommendation').empty(); $('#recommendation').empty();
if (!isBest) { if (!isBest) {
$('#recommendation').html('Must be at least 8 characters').css('color', 'red'); //$('#recommendation').html('Must be at least 8 characters').css('color', 'red');
$('#recommendation').html('Das Passwort muss mindestens 8 Zeichen haben').css('color', 'red');
} }
// match or not? // match or not?
if ($('#inputNewPwd').val() == $('#inputConfirm').val()) { if ($('#inputNewPwd').val() == $('#inputConfirm').val()) {
$('#message').html('Matching').css('color', 'green'); //$('#message').html('Matching').css('color', 'green');
$('#message').html('Übereinstimmend').css('color', 'green');
isMatch = true; isMatch = true;
} else { } else {
$('#message').html('Not Matching').css('color', 'red'); //$('#message').html('Not Matching').css('color', 'red');
$('#message').html('Nicht übereinstimmend').css('color', 'red');
isMatch = false; isMatch = false;
} }
......
extends layout
block content
if user !== null
h1 Hello, #{user.firstName}
a(href="/profile") Profile
br
a(href="/logout") Logout
else
h1 Welcome
br
a(href="/login") Login
<!DOCTYPE html>
<html lang="en">
<head>
<title>User Profile</title>
<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" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css" integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay" crossorigin="anonymous" />
<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;
}
</style>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script>
$(function(){
$("#header").load("fragment/header.html");
$("#footer").load("fragment/footer.html");
});
</script>
</head>
<body>
<!-- CONTENT -->
<div class="container-fluid">
<div class="row">
<!-- https://getbootstrap.com/docs/4.3/components/navs/ -->
<div class="col-3">
<h5>
<!-- TODO: Firstname + Lastname-->
<span>TODO: Firstname + Lastname</span>
</h5>
<div class="nav flex-column nav-pills" id="v-pills-tab" role="tablist" aria-orientation="vertical">
<a class="nav-link" href="#" aria-selected="true">Profile</a>
<a class="nav-link" href="#" aria-selected="false">Security</a>
<a class="nav-link" href="#" aria-selected="false">Services</a>
</div>
</div>
<div class="col-sm-9">
<form>
<p><input type="hidden" th:value="${id}"/></p>
<table class="table table-borderless">
<tr>
<th><label for="title">Title</label></th>
<td><input type="text" placeholder="Title"></td>
</tr>
<tr>
<th><label for="firstname">Vorname</label></th>
<td><input type="text" placeholder="Vorname"></td>
</tr>
<tr>
<th><label for="lastname">Nachname</label></th>
<td><input type="text" placeholder="Nachname"></td>
</tr>
<tr>
<th><label for="email">Email</label></th>
<td><input type="text" placeholder="Email"></td>
</tr>
<tr>
<th><label for="email">Unternehmen</label></th>
<td><input type="text" placeholder="Unternehmen"></td>
</tr>
<tr>
<th><label for="email">Branche</label></th>
<td><input type="text" placeholder="Branche"></td>
</tr>
<tr>
<th><label for="email">Fachgebiete</label></th>
<td><input type="text" placeholder="Fachgebiete"></td>
</tr>
</table>
<p><input type="submit" class="btn btn-primary" value="Update" disabled></p>
</form>
</div>
</div>
</div>
<!-- HEADER & FOOTER -->
<script src="https://transfer.hft-stuttgart.de/js/headfoot.js"></script>
</body>
</html>
\ No newline at end of file
include profile.html
\ No newline at end of file
...@@ -57,7 +57,7 @@ var methods = { ...@@ -57,7 +57,7 @@ var methods = {
}) })
}, },
getUserByEmail: function(email, callback) { getUserByEmail: function(email, callback) {
dbconn.user.query('SELECT title, firstname, lastname, industry, organisation, speciality FROM user WHERE email = "' +email+'"', function (err, rows, fields) { dbconn.user.query('SELECT salutation, title, firstname, lastname, industry, organisation, speciality FROM user WHERE email = "' +email+'"', function (err, rows, fields) {
if (err) { if (err) {
throw err; throw err;
} }
...@@ -143,6 +143,12 @@ var methods = { ...@@ -143,6 +143,12 @@ var methods = {
dbconn.project.query('CALL getAllLists', function (err, rows, fields){ dbconn.project.query('CALL getAllLists', function (err, rows, fields){
if (err) throw err; if (err) throw err;
callback(rows[0], err); callback(rows[0], err);
})
},
addProjectOverview: function(data, callback) {
dbconn.project.query('INSERT INTO project_overview SET ?', data, function (err, rows, fields){
if (err) throw err;
callback(err);
}) })
} }
}; };
......
...@@ -11,7 +11,7 @@ const async = require('async') ...@@ -11,7 +11,7 @@ const async = require('async')
const crypto = require('crypto') const crypto = require('crypto')
const nodemailer = require('nodemailer') const nodemailer = require('nodemailer')
module.exports = function (app, config, passport) { module.exports = function (app, config, passport, i18n) {
// =========== PASSPORT ======= // =========== PASSPORT =======
passport.serializeUser(function (user, done) { passport.serializeUser(function (user, done) {
...@@ -54,17 +54,6 @@ module.exports = function (app, config, passport) { ...@@ -54,17 +54,6 @@ module.exports = function (app, config, passport) {
passport.use(samlStrategy); passport.use(samlStrategy);
// ============================
/*
app.all('/', function(req, res){
req.flash('test', 'it worked');
res.redirect('/test')
});
app.all('/test', function(req, res){
res.send(JSON.stringify(req.flash('test')));
});
*/
// ============= SAML ============== // ============= SAML ==============
app.post(config.passport.saml.path, app.post(config.passport.saml.path,
passport.authenticate(config.passport.strategy, passport.authenticate(config.passport.strategy,
...@@ -107,18 +96,41 @@ module.exports = function (app, config, passport) { ...@@ -107,18 +96,41 @@ module.exports = function (app, config, passport) {
text: "" text: ""
}; };
var updatePasswordMailContent = "Hello,\n\n"+ var updatePasswordMailSubject = "Ihr Passwort für das Transferportal wurde gespeichert."
"We would like to notify that your password has been successfully updated.\n\n"+ var mailSignature = "Mit den besten Grüßen,\ndas Transferportal-Team der HFT Stuttgart\n\n"+
"Thanks,\nM4_LAB Team" "Transferportal der Hochschule für Technik Stuttgart\n"+
var updatePasswordMailSubject = "Your M4_LAB Password has been updated" "Schellingstr. 24\n"+
"70174 Stuttgart\n"+
"m4lab@hft-stuttgart.de\n"+
"https://transfer.hft-stuttgart.de"
var updatePasswordMailContent = "Lieber Nutzer,\n\n"+"Ihr Passwort wurde erfolgreich geändert.\n\n"+mailSignature
// ================ test i18n ==================
i18n.setLocale('de');
app.get('/de', function(req, res) {
var greeting = i18n.__('Hello World')
res.send(greeting)
});
// ======== APP ROUTES ==================== var lang = 'DE'
// ======== APP ROUTES - ACCOUNT ====================
app.get('/', function (req, res) { app.get('/', function (req, res) {
res.redirect('/account/profile') if (req.isAuthenticated()) {
methods.getUserByEmail(req.user.email, function(data, err){
if (!err) {
res.render(lang+'/account/home', {
user: data
});
}
})
} else {
res.redirect('/login'); // localhost
}
}); });
app.get('/error', function (req, res) { app.get('/error', function (req, res) {
res.render('error') res.render(lang+'/error')
}); });
app.get('/login', app.get('/login',
...@@ -155,7 +167,7 @@ module.exports = function (app, config, passport) { ...@@ -155,7 +167,7 @@ module.exports = function (app, config, passport) {
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('profile', { res.render(lang+'/account/profile', {
user: data, user: data,
email: req.user.email email: req.user.email
}); });
...@@ -219,7 +231,7 @@ module.exports = function (app, config, passport) { ...@@ -219,7 +231,7 @@ module.exports = function (app, config, passport) {
} }
// render the page // render the page
res.render('services', { res.render(lang+'/account/services', {
user: req.user, user: req.user,
project: allProjects project: allProjects
}); });
...@@ -232,7 +244,7 @@ module.exports = function (app, config, passport) { ...@@ -232,7 +244,7 @@ module.exports = function (app, config, passport) {
app.get('/security', function (req, res) { app.get('/security', function (req, res) {
if (req.isAuthenticated()) { if (req.isAuthenticated()) {
res.render('security', { res.render(lang+'/account/security', {
user: req.user // useful for view engine, useless for HTML user: req.user // useful for view engine, useless for HTML
}); });
} else { } else {
...@@ -242,6 +254,7 @@ module.exports = function (app, config, passport) { ...@@ -242,6 +254,7 @@ module.exports = function (app, config, passport) {
app.post('/updateProfile', function (req, res) { app.post('/updateProfile', function (req, res) {
var userData = { var userData = {
salutation: req.body.inputSalutation,
title: req.body.inputTitle, title: req.body.inputTitle,
firstname: req.body.inputFirstname, firstname: req.body.inputFirstname,
lastname: req.body.inputLastname, lastname: req.body.inputLastname,
...@@ -292,7 +305,9 @@ module.exports = function (app, config, passport) { ...@@ -292,7 +305,9 @@ module.exports = function (app, config, passport) {
throw err throw err
} }
else if (!isMatch) { else if (!isMatch) {
req.flash('error', "Sorry, your password was incorrect. Please double-check your password.") //req.flash('error', "Sorry, your password was incorrect. Please double-check your password.")
req.flash('error', "Das Passwort ist leider falsch. Bitte überprüfen Sie Ihre Eingabe.")
//res.redirect('/account/security')
res.redirect('/account/security') res.redirect('/account/security')
} }
else { else {
...@@ -310,13 +325,16 @@ module.exports = function (app, config, passport) { ...@@ -310,13 +325,16 @@ module.exports = function (app, config, passport) {
} }
methods.updateCredential(credentialData, function(err){ methods.updateCredential(credentialData, function(err){
if (err) { if (err) {
req.flash('error', "Database error: Password cannot be modified.") //req.flash('error', "Database error: Password cannot be modified.")
req.flash('error', "Datenbankfehler: Passwort kann nicht geändert werden.")
throw err throw err
} }
else { else {
req.flash('success', "Pasword updated!") //req.flash('success', "Pasword updated!")
req.flash('success', "Passwort aktualisiert!")
mailOptions.to = req.user.email mailOptions.to = req.user.email
mailOptions.subject = "Your M4_LAB Password has been updated" //mailOptions.subject = "Your M4_LAB Password has been updated."
mailOptions.subject = updatePasswordMailSubject
mailOptions.text = updatePasswordMailContent mailOptions.text = updatePasswordMailContent
smtpTransport.sendMail(mailOptions, function(err) { smtpTransport.sendMail(mailOptions, function(err) {
if (err) { if (err) {
...@@ -341,7 +359,7 @@ module.exports = function (app, config, passport) { ...@@ -341,7 +359,7 @@ module.exports = function (app, config, passport) {
}); });
app.get('/forgotPwd', function (req, res) { app.get('/forgotPwd', function (req, res) {
res.render('forgotPwd', { res.render(lang+'/account/forgotPwd', {
user: req.user user: req.user
}); });
}); });
...@@ -350,10 +368,10 @@ module.exports = function (app, config, passport) { ...@@ -350,10 +368,10 @@ module.exports = function (app, config, passport) {
//methods.currentDate(); //methods.currentDate();
var emailAddress = req.body.inputEmail; var emailAddress = req.body.inputEmail;
var emailContent = "Hi there,\n\n"+ /* 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"+ "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"; "Thanks,\nM4_LAB Team";
var emailSubject = "Account Access Attempted"; var emailSubject = "Account Access Attempted"; */
async.waterfall([ async.waterfall([
function(done) { function(done) {
...@@ -366,13 +384,19 @@ module.exports = function (app, config, passport) { ...@@ -366,13 +384,19 @@ module.exports = function (app, config, passport) {
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");
emailSubject = "M4_LAB Password Reset"; //var emailSubject = "M4_LAB Password Reset";
emailContent = "Hi User,\n\n"+ 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"+ "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" + "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"+ "This password reset is only valid for 1 hour.\n\n"+
"Thanks,\nM4_LAB Team" "Thanks,\nM4_LAB Team" */
var emailContent = "Lieber Nutzer,\n\n"+
"wir haben Ihre Anfrage zur Erneuerung Ihres Passwortes erhalten. Falls Sie diese Anfrage nicht gesendet haben, ignorieren Sie bitte diese E-Mail.\n\n"+
//"Sie können Ihr Passwort mit dem Klick auf diesen Link ändern: http://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
"Dieser Link ist aus Sicherheitsgründen nur für 1 Stunde gültig.\n\n"+mailSignature
var credentialData = { var credentialData = {
user_id: user.id, user_id: user.id,
resetPasswordToken: token, resetPasswordToken: token,
...@@ -381,39 +405,45 @@ module.exports = function (app, config, passport) { ...@@ -381,39 +405,45 @@ module.exports = function (app, config, passport) {
methods.updateCredential(credentialData, function(err) { methods.updateCredential(credentialData, function(err) {
done(err, token, user); done(err, token, user);
}); });
// send email
mailOptions.to = emailAddress;
mailOptions.subject = emailSubject;
mailOptions.text = emailContent;
smtpTransport.sendMail(mailOptions, function(err) {
done(err, 'done');
});
} }
else { else {
done(err, null, null); //done(err, null, null);
done(err, 'no user found');
} }
}); });
},
function(token, user, done) {
mailOptions.to = emailAddress;
mailOptions.subject = emailSubject;
mailOptions.text = emailContent;
smtpTransport.sendMail(mailOptions, function(err) {
done(err, 'done');
});
} }
], function(err) { ], function(err) {
if (err) { if (err) {
req.flash('error', 'An error occured. Please try again.'); //req.flash('error', 'An error occured. Please try again.');
req.flash('error', 'Ein Fehler ist aufgetreten. Bitte versuchen Sie es erneut.');
} }
else { else {
req.flash('success', 'An e-mail has been sent to ' + emailAddress + ' with further instructions.'); //req.flash('success', 'If your email is registered, an e-mail has been sent to ' + emailAddress + ' with further instructions.');
req.flash('success', 'Wenn Ihre E-Mail-Adresse registriert ist, wurde eine E-Mail mit dem weiteren Vorgehen an ' + emailAddress + ' versendet.');
} }
res.redirect('/account/forgotPwd'); //res.redirect('/account/forgotPwd'); // deployment
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.'); //req.flash('error', 'Password reset token is invalid or has expired.');
res.redirect('/account/forgotPwd'); req.flash('error', 'Der Schlüssel zum zurücksetzen des Passworts ist ungültig oder abgelaufen.');
//res.redirect('/account/forgotPwd'); // deployment
res.redirect('/account/forgotPwd'); // localhost
} }
else { else {
res.render('reset'); res.render(lang+'/account/reset');
} }
}); });
}); });
...@@ -432,11 +462,13 @@ module.exports = function (app, config, passport) { ...@@ -432,11 +462,13 @@ module.exports = function (app, config, passport) {
// 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.") //req.flash('error', "Database error: Password cannot be modified.")
req.flash('error', "Datenbankfehler: Passwort kann nicht geändert werden.")
throw err throw err
} }
else { else {
req.flash('success', "Your pasword has been updated.") //req.flash('success', "Your pasword has been updated.")
req.flash('success', "Passwort aktualisiert!")
// send notifiaction email // send notifiaction email
mailOptions.to = user.email mailOptions.to = user.email
mailOptions.subject = updatePasswordMailSubject mailOptions.subject = updatePasswordMailSubject
...@@ -463,7 +495,7 @@ module.exports = function (app, config, passport) { ...@@ -463,7 +495,7 @@ module.exports = function (app, config, passport) {
// todo: user registration with captcha // todo: user registration with captcha
app.get('/registration', function(req, res) { app.get('/registration', function(req, res) {
res.render('registration') res.render(lang+'/account/registration')
}) })
app.post('/registration', function(req, res) { app.post('/registration', function(req, res) {
...@@ -474,6 +506,7 @@ module.exports = function (app, config, passport) { ...@@ -474,6 +506,7 @@ module.exports = function (app, config, passport) {
// user data // user data
var curDate = new Date() var curDate = new Date()
var userData = { var userData = {
salutation: req.body.inputSalutation,
title: req.body.inputTitle, title: req.body.inputTitle,
firstname: req.body.inputFirstname, firstname: req.body.inputFirstname,
lastname: req.body.inputLastname, lastname: req.body.inputLastname,
...@@ -493,10 +526,12 @@ module.exports = function (app, config, passport) { ...@@ -493,10 +526,12 @@ module.exports = function (app, config, passport) {
} }
methods.registerNewUser(newAccount, function(err){ methods.registerNewUser(newAccount, function(err){
if (err) { if (err) {
req.flash('error', "Failed"); //req.flash('error', "Failed")
req.flash('error', "Fehlgeschlagen")
} }
else { else {
req.flash('success', 'Your account has been created. Please log in.'); //req.flash('success', 'Your account has been created. Please log in.')
req.flash('success', 'Ihr Benutzerkonto wurde angelegt. Bitte melden Sie sich an.')
} }
res.redirect('/account/registration'); res.redirect('/account/registration');
}) })
...@@ -504,7 +539,6 @@ module.exports = function (app, config, passport) { ...@@ -504,7 +539,6 @@ module.exports = function (app, config, passport) {
}); });
}) })
app.get('/email/:email', function(req, res) { app.get('/email/:email', function(req, res) {
methods.checkUserEmail(req.params.email, function(err, user){ methods.checkUserEmail(req.params.email, function(err, user){
if (!err) { if (!err) {
...@@ -546,4 +580,115 @@ module.exports = function (app, config, passport) { ...@@ -546,4 +580,115 @@ module.exports = function (app, config, passport) {
} }
]) ])
}); });
};
// ======== APP ROUTES - PROJECT ====================
app.get('/project', function (req, res) {
async.waterfall([
// get all projects from projectdb
function(done) {
methods.getAllProjects(function(projectsOverview, err) {
if (!err) {
done(err, projectsOverview)
}
})
},
// create JSON object for front-end
function(projectsOverview, done) {
var activeProjects = []
var nonActiveProjects = []
for (var i = 0; i < projectsOverview.length; i++) {
var project = {
id: projectsOverview[i].id,
logo: projectsOverview[i].logo,
akronym: projectsOverview[i].pname,
title: projectsOverview[i].title,
summary: projectsOverview[i].onelinesummary,
category: projectsOverview[i].category,
cp: projectsOverview[i].contact_email,
gitlab: projectsOverview[i].gitlab
}
if (projectsOverview[i].projectstatus == 0) {
nonActiveProjects.push(project)
}
else if (projectsOverview[i].projectstatus == 1) {
activeProjects.push(project)
}
}
// render the page
if (req.isAuthenticated()) {
res.render(lang+'/project/projects', {
isUserAuthenticated: true,
nonActive: nonActiveProjects,
active: activeProjects
});
}
else {
res.render(lang+'/project/projects', {
isUserAuthenticated: false,
nonActive: nonActiveProjects,
active: activeProjects
});
}
}
])
})
app.get('/addprojectoverview', function (req, res) {
if (req.isAuthenticated()) {
res.render(lang+'/project/addProjectOverview')
}
else {
res.redirect('/login')
}
})
app.post('/addprojectoverview', function (req, res) {
if (req.isAuthenticated()) {
var wiki = 0
if (req.body.wiki)
wiki = 1
var projectOverviewData = {
pname: req.body.pname,
title: req.body.title,
onelinesummary: req.body.summary,
category: req.body.category,
logo: req.body.logo,
gitlab: req.body.gitlabURL,
wiki: wiki,
overview: req.body.overview,
question: req.body.question,
approach: req.body.approach,
result: req.body.result,
keywords: req.body.keywords,
announcement: req.body.announcement,
term: req.body.term,
further_details: req.body.furtherDetails,
website: req.body.website,
src: req.body.src,
caption: req.body.caption,
contact_firstname: req.body.contactFirstname,
contact_lastname: req.body.contactLastname,
contact_email: req.body.contactEmail,
leader_firstname: req.body.leaderFirstname,
leader_lastname: req.body.leaderLastname,
leader_email: req.body.leaderEmail
}
methods.addProjectOverview(projectOverviewData, function(err){
if (err) {
//req.flash('error', "Failed")
req.flash('error', "Fehlgeschlagen")
res.redirect('/addProjectOverview');
}
else {
req.flash('success', 'Your project has been created.')
res.redirect('/project');
}
})
}
})
};
\ No newline at end of file
doctype html
html(lang="de")
head
title= "Forgot Password"
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")
link(rel="stylesheet", type="text/css", href="https://transfer.hft-stuttgart.de/css/custom/login.css")
link(rel="stylesheet", href="https://use.fontawesome.com/releases/v5.8.2/css/all.css", integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay", crossorigin="anonymous")
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;
}
body
div(class="container-fluid")
div(class="row")
div(class="col-md-6 offset-md-3")
if successes
for success in successes
div.alert.alert-success.alert-dismissible #{ success }
a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
if errors
for error, i in errors
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")
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")
input#inputEmail(name="inputEmail", type="email", class="form-control", placeholder="E-Mail-Adresse" required)
br
input(type="submit", class="btn btn-outline-dark btn-block", value="Passwort zurücksetzen")
// 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")
// 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="https://transfer.hft-stuttgart.de/js/headfoot.js")
doctype html
html(lang="de")
head
title= "User Account"
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")
link(rel="stylesheet", href="https://use.fontawesome.com/releases/v5.8.2/css/all.css", integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay", crossorigin="anonymous")
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;
}
body
div(class="container-fluid")
div(class="row")
div(class="col-3")
h5
span #{user.firstname} #{user.lastname}
div(class="nav flex-column nav-pills", id="v-pills-tab", role="tablist", aria-orientation="vertical")
a(class="nav-link" href="/profile" aria-selected="true") Benutzerprofil
a(class="nav-link" href="/security" aria-selected="false") Sicherheitseinstellungen
a(class="nav-link" href="/services" aria-selected="false") Projekte und Dienste
div(class="col-sm-9")
p content goes here
// 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")
// 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/headfootLogout.js")
\ No newline at end of file
doctype html
html(lang="de")
head
title= "User Profile"
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")
link(rel="stylesheet", href="https://use.fontawesome.com/releases/v5.8.2/css/all.css", integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay", crossorigin="anonymous")
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;
}
body
div(class="container-fluid")
div(class="row")
div(class="col-3")
h5
span #{user.firstname} #{user.lastname}
div(class="nav flex-column nav-pills", id="v-pills-tab", role="tablist", aria-orientation="vertical")
a(class="nav-link" href="#" aria-selected="true") Benutzerprofil
a(class="nav-link" href="/security" aria-selected="false") Sicherheitseinstellungen
a(class="nav-link" href="/services" aria-selected="false") Projekte und Dienste
div(class="col-sm-9")
if successes
for success in successes
div.alert.alert-success.alert-dismissible #{ success }
a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
if errors
for error, i in errors
div.alert.alert-danger.alert-dismissible.fade.show #{ error }
a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
form#profileForm(method="POST", action="/updateProfile")
div(class="form-row")
div(class='form-group col-md-2')
label(for="title") Anrede
select#inputSalutation(name="inputSalutation", class="form-control", , value=user.salutation)
option(value="") - Anrede -
option(value="Herr") Herr
option(value="Frau") Frau
option(value="Divers") Divers
script.
var salutationOptions = document.getElementById('inputSalutation').options;
for (i=0; i < salutationOptions.length; i++) {
if (salutationOptions[i].value == '#{user.salutation}')
salutationOptions[i].selected = true;
}
div(class='form-group col-md-2')
label(for="title") Titel
select#inputTitle(name="inputTitle", class="form-control", value=user.title)
option(value="") - Titel -
option(value="Prof.") Prof.
option(value="Dr.") Dr.
option(value="Dipl.-Ing.") Dipl.-Ing.
option(value="etc.") etc.
script.
var titleOptions = document.getElementById('inputTitle').options;
for (i=0; i < titleOptions.length; i++) {
if (titleOptions[i].value == '#{user.title}')
titleOptions[i].selected = true;
}
div(class='form-group col-md-2')
label(for="firstname") Vorname
input#inputFirstname(name="inputFirstname", type="text", class="form-control", placeholder="Vorname", value=user.firstname required)
div(class='form-group col-md-2')
label(for="lastname") Nachname
input#inputLastname(name="inputLastname", type="text", class="form-control", placeholder="Nachname", value=user.lastname required)
div(class="form-row")
div(class='form-group col-md-8')
label(for="email") E-mail Adresse
input#inputEmail(name="inputEmail", type="email", class="form-control", placeholder="Email", value=email required)
div(class="form-row")
div(class='form-group col-md-8')
label(for="organisation") Unternehmen
input#inputOrganisation(name="inputOrganisation", type="text", class="form-control", placeholder="Unternehmen", value=user.organisation)
div(class="form-row")
div(class='form-group col-md-8')
label(for="industry") Branche
input#inputIndustry(name="inputIndustry", type="text", class="form-control", placeholder="Branche", value=user.industry)
div(class="form-row")
div(class='form-group col-md-8')
label(for="speciality") Fachgebiete
input#inputSpeciality(name="inputSpeciality", type="text", class="form-control", placeholder="Fachgebiete", value=user.speciality)
input(type="submit", class="btn btn-primary", value="Speichern")
// 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")
// 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/headfootLogout.js")
\ No newline at end of file
doctype html
html(lang="de")
head
title= "Create New Account"
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")
link(rel="stylesheet", href="https://use.fontawesome.com/releases/v5.8.2/css/all.css", integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay", crossorigin="anonymous")
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 {
color: red;
font-size: 11px;
}
body
div(class="container-fluid")
div(class="row")
div(class="col-md-6 offset-md-2")
h3(class="mb-3 font-weight-bold") Neues Benutzerkonto anlegen
div(class="col-md-6 offset-md-3")
if successes
for success in successes
div.alert.alert-success.alert-dismissible #{ success }
a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
if errors
for error, i in errors
div.alert.alert-danger.alert-dismissible.fade.show #{ error }
a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
form(method="POST")
h5(class="mb-3 font-weight-bold") Anmeldedaten
div(class='form-row')
div(class='form-group col-md-6')
input#inputEmail(name="inputEmail", type="email", class="form-control", placeholder="E-Mail-Adresse*" required)
span#emailWarning(class='warning')
div(class="form-group col-md-6")
input#inputPassword(name="inputPassword", type="password", class="form-control", data-toggle="password", placeholder="Passwort*" required)
span#passwordWarning(class='warning')
h5(class="mb-3 font-weight-bold") Benutzerprofil
div(class="form-row")
div(class='form-group col-md-2')
select#inputSalutation(name="inputSalutation", class="form-control")
option(value="") - Anrede -
option(value="Herr") Herr
option(value="Frau") Frau
option(value="Divers") Divers
div(class='form-group col-md-2')
select#inputTitle(name="inputTitle", class="form-control")
option(value="") - Titel -
option(value="Prof.") Prof.
option(value="Dr.") Dr.
option(value="Dipl.-Ing.") Dipl.-Ing.
option(value="etc.") etc.
div(class='form-group col-md-4')
input#inputFirstname(name="inputFirstname", type="text", class="form-control", placeholder="Vorname*" required)
div(class='form-group col-md-4')
input#inputLastname(name="inputLastname", type="text", class="form-control", placeholder="Nachname*" required)
div(class="form-group")
input#inputOrganisation(name="inputOrganisation", type="text", class="form-control", placeholder="Unternehmen")
div(class="form-group")
input#inputIndustry(name="inputIndustry", type="text", class="form-control", placeholder="Branche")
div(class="form-group")
input#inputSpeciality(name="inputSpeciality", type="text", class="form-control", placeholder="Fachgebiete")
p <em><small>* Pflichtfeld</small></em>
input#submitBtn(type="submit", class="btn btn-outline-dark btn-block", value="Senden" disabled)
br
p(class="text-center") Sie haben bereits ein Benutzerkonto? <a href="/login">Melden Sie sich hier an</a>.
// 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")
// Bootstrap
script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous")
// toggle password
script(src='https://unpkg.com/bootstrap-show-password@1.2.1/dist/bootstrap-show-password.min.js')
// M4_LAB
script(src="/js/generalFunction.js")
script(src="/js/registration.js")
script(src="https://transfer.hft-stuttgart.de/js/headfoot.js")
\ No newline at end of file
doctype html
html(lang="de")
head
title= "Reset Password"
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")
link(rel="stylesheet", type="text/css", href="https://transfer.hft-stuttgart.de/css/custom/login.css")
link(rel="stylesheet", href="https://use.fontawesome.com/releases/v5.8.2/css/all.css", integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay", crossorigin="anonymous")
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;
}
body
div(class="container-fluid")
div(class="row")
div(class="col-md-6 offset-md-3")
if successes
for success in successes
div.alert.alert-success.alert-dismissible #{ success }
a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
if errors
for error, i in errors
div.alert.alert-danger.alert-dismissible.fade.show #{ error }
a(class="close", href="#", data-dismiss="alert", aria-label="close") &times;
form#forgotForm(method="POST", class="form-signin")
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")
input#inputNewPwd(name="inputNewPwd", type="password", class="form-control", placeholder="Neues Passwort" required)
span#recommendation(class='warning')
input#inputConfirm(name="inputConfirm", type="password", class="form-control", placeholder="Passwort bestätigen" required)
span#message(class='warning')
input#updateBtn(type="submit", class="btn btn-outline-dark btn-block", value="Passwort ändern" disabled)
// 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")
// 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/security.js")
script(src="/js/generalFunction.js")
script(src="https://transfer.hft-stuttgart.de/js/headfoot.js")
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