Added client-side password checking
parent
de827a5543
commit
fc80498f2d
|
@ -2,6 +2,7 @@
|
|||
|
||||
const slug = require('slug'),
|
||||
xss = require('xss'),
|
||||
mellt = require('mellt'),
|
||||
mw = require('../middleware.js'),
|
||||
User = require('../models.js').user,
|
||||
mail = require('../mail.js'),
|
||||
|
@ -130,37 +131,45 @@ router.route('/password/:token')
|
|||
.get( (req,res)=>{
|
||||
res.render('password');
|
||||
} )
|
||||
|
||||
|
||||
// Set new password
|
||||
.post( (req,res,next)=>{
|
||||
|
||||
//TODO: Validate password
|
||||
|
||||
// Delete token
|
||||
res.locals.passwordUser.auth.passToken = undefined;
|
||||
res.locals.passwordUser.auth.tokenExpires = undefined;
|
||||
|
||||
// Create hash
|
||||
res.locals.passwordUser.generateHash( req.body.password, (err,hash)=>{
|
||||
if (err){
|
||||
mw.throwErr(err,req);
|
||||
res.redirect(`/password/${req.params.token}`);
|
||||
}
|
||||
else {
|
||||
|
||||
// Save new password to db
|
||||
res.locals.passwordUser.auth.password = hash;
|
||||
res.locals.passwordUser.save()
|
||||
.then( ()=>{
|
||||
req.flash('success', 'Password set. You can use it to log in now. ');
|
||||
res.redirect('/login#login');
|
||||
})
|
||||
.catch( (err)=>{
|
||||
mw.throwErr(err,req);
|
||||
res.redirect('/login#signup');
|
||||
});
|
||||
|
||||
}
|
||||
} );
|
||||
// Validate password
|
||||
let daysToCrack = mellt.CheckPassword(req.body.password);
|
||||
if (daysToCrack<10) {
|
||||
mw.throwErr(new Error(`That password could be cracked in ${daysToCrack} days! Come up with a more complex password that would take at least 10 days to crack. `));
|
||||
res.redirect(`/settings/password/${req.params.token}`);
|
||||
} else {
|
||||
|
||||
// Delete token
|
||||
res.locals.passwordUser.auth.passToken = undefined;
|
||||
res.locals.passwordUser.auth.tokenExpires = undefined;
|
||||
|
||||
// Create hash
|
||||
res.locals.passwordUser.generateHash( req.body.password, (err,hash)=>{
|
||||
if (err){
|
||||
mw.throwErr(err,req);
|
||||
res.redirect(`/password/${req.params.token}`);
|
||||
}
|
||||
else {
|
||||
|
||||
// Save new password to db
|
||||
res.locals.passwordUser.auth.password = hash;
|
||||
res.locals.passwordUser.save()
|
||||
.then( ()=>{
|
||||
req.flash('success', 'Password set. You can use it to log in now. ');
|
||||
res.redirect('/login#login');
|
||||
})
|
||||
.catch( (err)=>{
|
||||
mw.throwErr(err,req);
|
||||
res.redirect('/login#signup');
|
||||
});
|
||||
|
||||
}
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
|
|
|
@ -13,17 +13,23 @@ router
|
|||
subject: 'Test email',
|
||||
text: mail.text("Looks like everything's working! "),
|
||||
html: mail.html("<p>Looks like everything's working! </p>")
|
||||
}).then(()=>{
|
||||
})
|
||||
.then(()=>{
|
||||
console.log("Test email should have sent...");
|
||||
res.sendStatus(200);
|
||||
}).catch((err)=>{
|
||||
})
|
||||
.catch((err)=>{
|
||||
mw.throwErr(err,req);
|
||||
next();
|
||||
res.sendStatus(500);
|
||||
});
|
||||
})
|
||||
|
||||
.get('/password', (req,res)=>{
|
||||
res.render('password');
|
||||
})
|
||||
.post('/password', (req,res)=>{
|
||||
//TODO: Server-side checks
|
||||
res.sendStatus(200);
|
||||
});
|
||||
|
||||
module.exports = router;
|
|
@ -13,6 +13,7 @@
|
|||
"express-validator": "^3.1.3",
|
||||
"firebase": "^3.7.2",
|
||||
"kerberos": "0.0.17",
|
||||
"mellt": "^1.0.0",
|
||||
"moment": "^2.12.0",
|
||||
"mongodb": "^2.1.4",
|
||||
"mongoose": "^4.9.0",
|
||||
|
|
|
@ -87,6 +87,8 @@ pre {
|
|||
.hide { display: none !important; }
|
||||
.red, .red:hover { color: #fb6e3d !important; }
|
||||
.yellow, .yellow:hover { color: #fbc93d !important; }
|
||||
.green, .green:hover { color: #8ae137 !important; }
|
||||
|
||||
.shadow {
|
||||
-moz-box-shadow: .18vw .18vw .36vw #000;
|
||||
-webkit-box-shadow: .18vw .18vw .36vw #000;
|
||||
|
@ -134,13 +136,13 @@ section {
|
|||
font-weight:600;
|
||||
display: inline-block;
|
||||
padding: 15px 30px;
|
||||
transition: 100ms;
|
||||
cursor: pointer;
|
||||
background: rgba(255,255,255,0.1);
|
||||
color: #eee;
|
||||
border: 1px solid #666;
|
||||
border-radius: .5vw;
|
||||
} .btn:not(.disabled) {
|
||||
} .btn:not(:disabled) {
|
||||
border: 1px solid #666;
|
||||
transition: 100ms;
|
||||
cursor: pointer;
|
||||
-moz-box-shadow:
|
||||
inset .11vw .18vw .52vw rgba(255,255,255,.2),
|
||||
inset -.11vw -.18vw .52vw rgba(0,0,0,.4),
|
||||
|
@ -153,10 +155,12 @@ section {
|
|||
inset .11vw .18vw .52vw rgba(255,255,255,.2),
|
||||
inset -.11vw -.18vw .52vw rgba(0,0,0,.4),
|
||||
.18vw .18vw .36vw #000;
|
||||
} .btn:hover:not(.disabled) {
|
||||
} .btn:disabled {
|
||||
border: 1px solid #999;
|
||||
} .btn:hover:not(:disabled) {
|
||||
text-decoration: none;
|
||||
background: rgba(255,255,255,0.2);
|
||||
} .btn:active:not(.disabled) {
|
||||
} .btn:active:not(:disabled) {
|
||||
-moz-box-shadow:
|
||||
inset .11vw .18vw .52vw rgba(0,0,0,.4),
|
||||
inset -.11vw -.18vw .52vw rgba(255,255,255,.2);
|
||||
|
@ -166,10 +170,10 @@ section {
|
|||
box-shadow:
|
||||
inset .11vw .18vw .52vw rgba(0,0,0,.4),
|
||||
inset -.11vw -.18vw .52vw rgba(255,255,255,.2);
|
||||
} .btn:focus:not(.disabled){
|
||||
} .btn:focus:not(:disabled){
|
||||
border: 1px solid #fbc93d;
|
||||
}
|
||||
.btn.main {
|
||||
.btn.main:not(:disabled) {
|
||||
color: #fbc93d;
|
||||
}
|
||||
.btn .fa {
|
||||
|
|
|
@ -17,16 +17,21 @@ form label {
|
|||
|
||||
/* Input formatting */
|
||||
form input, form textarea, form select {
|
||||
-moz-box-shadow: inset .11vw .18vw .25vw rgba(0,0,0,.5);
|
||||
-webkit-box-shadow: inset .11vw .18vw .25vw rgba(0,0,0,.5);
|
||||
box-shadow: inset .11vw .18vw .25vw rgba(0,0,0,.5);
|
||||
color: #eee;
|
||||
background-color: #202020;
|
||||
background-color: rgba(255,255,255,0.1);
|
||||
padding: 1% 1.5%;
|
||||
border: 1px solid #666;
|
||||
border-radius: .3vw;
|
||||
}
|
||||
form input:not(:disabled), form textarea:not(:disabled), form select:not(:disabled) {
|
||||
border: 1px solid #666;
|
||||
-moz-box-shadow: inset .11vw .18vw .25vw rgba(0,0,0,.5);
|
||||
-webkit-box-shadow: inset .11vw .18vw .25vw rgba(0,0,0,.5);
|
||||
box-shadow: inset .11vw .18vw .25vw rgba(0,0,0,.5);
|
||||
}
|
||||
form input:disabled, form textarea:disabled form select:disabled {
|
||||
border: 1px solid #999;
|
||||
}
|
||||
form input:not(.input-addon):not(.input-with-addon):not([type="radio"]):not([type="checkbox"]),
|
||||
form .input-with-addon-group {
|
||||
min-width: 50%;
|
||||
|
|
|
@ -13,24 +13,40 @@
|
|||
|
||||
<form id='password-form' role="form" method="post">
|
||||
<style>
|
||||
#password input {
|
||||
#password-form .password {
|
||||
min-width: 40%;
|
||||
margin-bottom: 2%;
|
||||
}
|
||||
#password-help {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Your password must be at least 8 characters long. You can use any letter, number, symbol, emoji, or spaces. Your password will be stored as a secure hash on the server. </p>
|
||||
|
||||
<div id='password' class='form-group' title="Type your new password here">
|
||||
<input class='form-control' name="password" type="password" placeholder="enter password" minlength="8" maxlength="160">
|
||||
<input class='form-control' name="repassword" type="password" placeholder="retype password" minlength="8" maxlength="160">
|
||||
|
||||
<p>Your password must be at least 8 characters long. You can use any letter, number, symbol, emoji, or spaces. Your password will be stored as a salted hash on the server. </p>
|
||||
|
||||
<div class='form-group' style="flex-wrap:wrap">
|
||||
<input id='p1' class='form-control password' name="password" type="password" placeholder="enter password" title="Type your new password here" minlength="8" maxlength="160">
|
||||
<input id='p2' class='form-control password' name="repassword" type="password" placeholder="retype password" title="Retype your new password here" minlength="8" maxlength="160">
|
||||
<span title="Show your passwords if nobody's looking over your shoulder. " style="margin:auto">
|
||||
<input id='show' name="show" type="checkbox">
|
||||
<label for="show">show</label>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p id='password-help' title="Your passwords are checked using Mellt password cracker. "></p>
|
||||
|
||||
<div id='submit-group' class='form-group flexbox' style="padding:0 0 60px; justify-content:space-around">
|
||||
<input class='btn yellow' style="width:50%; background:#333" type="submit" value="Save">
|
||||
<a href="#" class='btn'>cancel</a>
|
||||
<div id='submit-group' class='form-group flexbox' style="justify-content:space-around">
|
||||
<input id='submit' class='btn main' style="min-width:50%" type="submit" value="Save" title="You need to enter a password first. " disabled>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
||||
{% block javascript %}
|
||||
{{super()}}
|
||||
<script src="/static/js/.mellt.min.js"></script>
|
||||
<script src="/static/js/.common-passwords.min.js"></script>
|
||||
<script src="/static/js/.password.min.js"></script>
|
||||
{% endblock %}
|
Loading…
Reference in New Issue