mirror of
https://github.com/janishutz/libreevent.git
synced 2025-11-25 13:24:24 +00:00
pw reset done
This commit is contained in:
@@ -11,7 +11,6 @@ const express = require( 'express' );
|
|||||||
let app = express();
|
let app = express();
|
||||||
const path = require( 'path' );
|
const path = require( 'path' );
|
||||||
const expressSession = require( 'express-session' );
|
const expressSession = require( 'express-session' );
|
||||||
const bodyParser = require( 'body-parser' );
|
|
||||||
const cookieParser = require( 'cookie-parser' );
|
const cookieParser = require( 'cookie-parser' );
|
||||||
const http = require( 'http' );
|
const http = require( 'http' );
|
||||||
const fs = require( 'fs' );
|
const fs = require( 'fs' );
|
||||||
@@ -77,7 +76,7 @@ app.use( expressSession( {
|
|||||||
// app.use( bodyParser.json() );
|
// app.use( bodyParser.json() );
|
||||||
app.use( cookieParser() );
|
app.use( cookieParser() );
|
||||||
|
|
||||||
let file = path.join( __dirname + '/../webapp/main/dist/index.html' );
|
let file = path.join( __dirname + '/webapp/index.html' );
|
||||||
|
|
||||||
console.log( '[ Server ] loading backend components' );
|
console.log( '[ Server ] loading backend components' );
|
||||||
if ( settings.init ) {
|
if ( settings.init ) {
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ class GETHandler {
|
|||||||
}
|
}
|
||||||
} else if ( call === 'getName' ) {
|
} else if ( call === 'getName' ) {
|
||||||
resolve( { 'name': settings.name } );
|
resolve( { 'name': settings.name } );
|
||||||
|
} else {
|
||||||
|
reject( { 'code': 404, 'message': 'Route not found' } );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
const path = require( 'path' );
|
const path = require( 'path' );
|
||||||
const db = require( '../db/db.js' );
|
const db = require( '../db/db.js' );
|
||||||
const fs = require( 'fs' );
|
const fs = require( 'fs' );
|
||||||
|
const pwHandler = require( '../credentials/pwdmanager.js' );
|
||||||
|
|
||||||
class POSTHandler {
|
class POSTHandler {
|
||||||
constructor () {
|
constructor () {
|
||||||
@@ -153,6 +154,18 @@ class POSTHandler {
|
|||||||
console.error( error );
|
console.error( error );
|
||||||
reject( { 'code': 500, 'message': 'ERR_DB' } );
|
reject( { 'code': 500, 'message': 'ERR_DB' } );
|
||||||
} );
|
} );
|
||||||
|
} else if ( call === 'resetPW' ) {
|
||||||
|
pwHandler.resetPassword( data.email ).then( () => {
|
||||||
|
resolve( 'ok' );
|
||||||
|
} ).catch( error => {
|
||||||
|
if ( error.code ) {
|
||||||
|
reject( error );
|
||||||
|
} else {
|
||||||
|
reject( { 'code': 500, 'message': error } );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
} else {
|
||||||
|
reject( { 'code': 404, 'message': 'Route not found' } );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,13 +65,7 @@ class TwoFA {
|
|||||||
else return 'invalid';
|
else return 'invalid';
|
||||||
}
|
}
|
||||||
|
|
||||||
generatePwdChangeToken () {
|
|
||||||
// TODO: Gen token and store in store
|
|
||||||
return 'test';
|
|
||||||
}
|
|
||||||
|
|
||||||
async generateTwoFAMail ( token, ip, domain, pageName ) {
|
async generateTwoFAMail ( token, ip, domain, pageName ) {
|
||||||
const tok = this.generatePwdChangeToken();
|
|
||||||
const app = createSSRApp( {
|
const app = createSSRApp( {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -79,7 +73,6 @@ class TwoFA {
|
|||||||
ip: ip,
|
ip: ip,
|
||||||
host: domain,
|
host: domain,
|
||||||
pageName: pageName,
|
pageName: pageName,
|
||||||
pwdChangeToken: tok,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
template: '' + fs.readFileSync( path.join( __dirname + '/twoFAMail.html' ) )
|
template: '' + fs.readFileSync( path.join( __dirname + '/twoFAMail.html' ) )
|
||||||
|
|||||||
@@ -15,6 +15,15 @@
|
|||||||
// import and init
|
// import and init
|
||||||
const bcrypt = require( 'bcrypt' );
|
const bcrypt = require( 'bcrypt' );
|
||||||
const db = require( '../db/db.js' );
|
const db = require( '../db/db.js' );
|
||||||
|
const mm = require( '../mail/mailSender.js' );
|
||||||
|
const mailManager = new mm();
|
||||||
|
const fs = require( 'fs' );
|
||||||
|
const path = require( 'path' );
|
||||||
|
const token = require( '../token.js' );
|
||||||
|
let createSSRApp = require( 'vue' ).createSSRApp;
|
||||||
|
let renderToString = require( 'vue/server-renderer' ).renderToString;
|
||||||
|
|
||||||
|
const settings = JSON.parse( fs.readFileSync( path.join( __dirname + '/../../config/settings.config.json' ) ) );
|
||||||
|
|
||||||
module.exports.checkpassword = function checkpassword ( email, password ) {
|
module.exports.checkpassword = function checkpassword ( email, password ) {
|
||||||
return new Promise( resolve => {
|
return new Promise( resolve => {
|
||||||
@@ -39,3 +48,32 @@ module.exports.hashPassword = ( password ) => {
|
|||||||
resolve( bcrypt.hashSync( password, 10 ) );
|
resolve( bcrypt.hashSync( password, 10 ) );
|
||||||
} );
|
} );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module.exports.resetPassword = ( email ) => {
|
||||||
|
return new Promise( ( resolve, reject ) => {
|
||||||
|
db.checkDataAvailability( 'users', 'email', email ).then( dat => {
|
||||||
|
if ( dat ) {
|
||||||
|
const newPW = token.generateToken( 20 );
|
||||||
|
this.hashPassword( newPW ).then( hash => {
|
||||||
|
( async () => {
|
||||||
|
db.writeDataSimple( 'users', 'email', email, { 'pass': hash } );
|
||||||
|
const app = createSSRApp( {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
password: newPW,
|
||||||
|
host: settings.yourDomain
|
||||||
|
};
|
||||||
|
},
|
||||||
|
template: '' + fs.readFileSync( path.join( __dirname + '/../../ui/en/signup/pwReset.html' ) )
|
||||||
|
} );
|
||||||
|
|
||||||
|
mailManager.sendMail( email, await renderToString( app ), 'Password reset', settings.mailSender );
|
||||||
|
resolve( 'ok' );
|
||||||
|
} )();
|
||||||
|
} );
|
||||||
|
} else {
|
||||||
|
reject( { 'code': 404, 'message': 'ERR_USER_NOT_FOUND' } );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
};
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<img :src="host + '/otherAssets/logo.png'" alt="Logo" class="logo">
|
<img :src="host + '/otherAssets/logo.png'" alt="Logo" class="logo">
|
||||||
<h1>Welcome back!</h1>
|
<h1>Welcome back!</h1>
|
||||||
<p>It looks like someone is trying to sign in to your account at {{ pageName }}. If it was you, please click the button below to confirm the login. If not, please <a :href="host + '/account/changePassword?token=' + pwdChangeToken">change</a> your password immediately.</p>
|
<p>It looks like someone is trying to sign in to your account at {{ pageName }}. If it was you, please click the button below to confirm the login. If not, please change your password immediately.</p>
|
||||||
<p class="ip">Logging in from IP {{ ip }}.</p>
|
<p class="ip">Logging in from IP {{ ip }}.</p>
|
||||||
<a :href="host + '/user/2fa?token=' + token" class="verify">Verify</a>
|
<a :href="host + '/user/2fa?token=' + token" class="verify">Verify</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
70
src/server/ui/en/signup/pwReset.html
Normal file
70
src/server/ui/en/signup/pwReset.html
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Two-Factor Authentication</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: sans-serif;
|
||||||
|
width: 100%;
|
||||||
|
height: 800px;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
width: 80%;
|
||||||
|
height: 90%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ip {
|
||||||
|
color: rgb(94, 94, 94);
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
width: 70vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify {
|
||||||
|
padding: 20px 30px;
|
||||||
|
background-color: rgb(0, 7, 87);
|
||||||
|
text-decoration: none;
|
||||||
|
color: white;
|
||||||
|
transition: 0.5s all;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.verify:hover {
|
||||||
|
background-color: rgb(0, 12, 139);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width: 999px) {
|
||||||
|
.logo {
|
||||||
|
width: 20vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
width: 40vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="content">
|
||||||
|
<img :src="host + '/otherAssets/logo.png'" alt="Logo" class="logo">
|
||||||
|
<h1>Password reset</h1>
|
||||||
|
<p>Your new password is:</p>
|
||||||
|
<p>{{ password }}</p>
|
||||||
|
<p>Use it to sign into your account now and change it as soon as you have logged in.</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
1
src/server/webapp
Symbolic link
1
src/server/webapp
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../webapp/main/dist/
|
||||||
@@ -32,10 +32,26 @@
|
|||||||
methods: {
|
methods: {
|
||||||
reset() {
|
reset() {
|
||||||
const startNotification = this.$refs.notification.createNotification( 'Starting password reset', 20, 'progress', 'normal' );
|
const startNotification = this.$refs.notification.createNotification( 'Starting password reset', 20, 'progress', 'normal' );
|
||||||
|
let fetchOptions = {
|
||||||
|
method: 'post',
|
||||||
|
body: JSON.stringify( {'email': this.email } ),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'charset': 'utf-8'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetch( localStorage.getItem( 'url' ) + '/API/resetPW', fetchOptions ).then( res => {
|
||||||
|
if ( res.status !== 200 ) {
|
||||||
this.$refs.notification.cancelNotification( startNotification );
|
this.$refs.notification.cancelNotification( startNotification );
|
||||||
this.$refs.notification.createNotification( 'An account with this email address does not exist.', 5, 'error', 'normal' );
|
this.$refs.notification.createNotification( 'An account with this email address does not exist.', 5, 'error', 'normal' );
|
||||||
|
} else {
|
||||||
this.$refs.notification.cancelNotification( startNotification );
|
this.$refs.notification.cancelNotification( startNotification );
|
||||||
this.$refs.notification.createNotification( 'Password reset email sent. Please follow the instructions given there.', 30, 'ok', 'normal' );
|
this.$refs.notification.createNotification( 'Password reset email sent. Please follow the instructions given there.', 30, 'ok', 'normal' );
|
||||||
|
setTimeout( () => {
|
||||||
|
location.href = '/login';
|
||||||
|
}, 10000 );
|
||||||
|
}
|
||||||
|
} );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,8 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<label for="news">Do you want to potentially get newsletter?</label><br>
|
<label for="news">Do you want to potentially get newsletter?</label><br>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
<input type="checkbox" v-model="formData[ 'newsletter' ]" name="news" id="news"><br><br>
|
<input type="checkbox" v-model="formData[ 'newsletter' ]" name="news" id="news"><br><br>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
Reference in New Issue
Block a user