diff --git a/src/server/app.js b/src/server/app.js index 95155f7..5220525 100644 --- a/src/server/app.js +++ b/src/server/app.js @@ -11,7 +11,6 @@ const express = require( 'express' ); let app = express(); const path = require( 'path' ); const expressSession = require( 'express-session' ); -const bodyParser = require( 'body-parser' ); const cookieParser = require( 'cookie-parser' ); const http = require( 'http' ); const fs = require( 'fs' ); @@ -77,7 +76,7 @@ app.use( expressSession( { // app.use( bodyParser.json() ); 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' ); if ( settings.init ) { diff --git a/src/server/backend/api/getHandler.js b/src/server/backend/api/getHandler.js index 69e9a76..acd6cdf 100644 --- a/src/server/backend/api/getHandler.js +++ b/src/server/backend/api/getHandler.js @@ -38,6 +38,8 @@ class GETHandler { } } else if ( call === 'getName' ) { resolve( { 'name': settings.name } ); + } else { + reject( { 'code': 404, 'message': 'Route not found' } ); } } ); } diff --git a/src/server/backend/api/postHandler.js b/src/server/backend/api/postHandler.js index 59c29d7..fbb7b20 100644 --- a/src/server/backend/api/postHandler.js +++ b/src/server/backend/api/postHandler.js @@ -10,6 +10,7 @@ const path = require( 'path' ); const db = require( '../db/db.js' ); const fs = require( 'fs' ); +const pwHandler = require( '../credentials/pwdmanager.js' ); class POSTHandler { constructor () { @@ -153,6 +154,18 @@ class POSTHandler { console.error( error ); 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' } ); } } ); } diff --git a/src/server/backend/credentials/2fa.js b/src/server/backend/credentials/2fa.js index 255783e..0f988c5 100644 --- a/src/server/backend/credentials/2fa.js +++ b/src/server/backend/credentials/2fa.js @@ -65,13 +65,7 @@ class TwoFA { else return 'invalid'; } - generatePwdChangeToken () { - // TODO: Gen token and store in store - return 'test'; - } - async generateTwoFAMail ( token, ip, domain, pageName ) { - const tok = this.generatePwdChangeToken(); const app = createSSRApp( { data() { return { @@ -79,7 +73,6 @@ class TwoFA { ip: ip, host: domain, pageName: pageName, - pwdChangeToken: tok, }; }, template: '' + fs.readFileSync( path.join( __dirname + '/twoFAMail.html' ) ) diff --git a/src/server/backend/credentials/pwdmanager.js b/src/server/backend/credentials/pwdmanager.js index d8f1e9b..6d8de01 100644 --- a/src/server/backend/credentials/pwdmanager.js +++ b/src/server/backend/credentials/pwdmanager.js @@ -15,6 +15,15 @@ // import and init const bcrypt = require( 'bcrypt' ); 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 ) { return new Promise( resolve => { @@ -38,4 +47,33 @@ module.exports.hashPassword = ( password ) => { return new Promise( resolve => { 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' } ); + } + } ); + } ); }; \ No newline at end of file diff --git a/src/server/backend/credentials/twoFAMail.html b/src/server/backend/credentials/twoFAMail.html index e6ac8b7..842a70e 100644 --- a/src/server/backend/credentials/twoFAMail.html +++ b/src/server/backend/credentials/twoFAMail.html @@ -62,7 +62,7 @@

Welcome back!

-

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.

+

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.

Logging in from IP {{ ip }}.

Verify
diff --git a/src/server/ui/en/signup/pwReset.html b/src/server/ui/en/signup/pwReset.html new file mode 100644 index 0000000..7fd0f1b --- /dev/null +++ b/src/server/ui/en/signup/pwReset.html @@ -0,0 +1,70 @@ + + + + + + Two-Factor Authentication + + + +
+ +

Password reset

+

Your new password is:

+

{{ password }}

+

Use it to sign into your account now and change it as soon as you have logged in.

+
+ + \ No newline at end of file diff --git a/src/server/webapp b/src/server/webapp new file mode 120000 index 0000000..2b6e2f3 --- /dev/null +++ b/src/server/webapp @@ -0,0 +1 @@ +../webapp/main/dist/ \ No newline at end of file diff --git a/src/webapp/main/src/views/user/PasswordResetView.vue b/src/webapp/main/src/views/user/PasswordResetView.vue index 51c019d..73c4f6e 100644 --- a/src/webapp/main/src/views/user/PasswordResetView.vue +++ b/src/webapp/main/src/views/user/PasswordResetView.vue @@ -32,10 +32,26 @@ methods: { reset() { const startNotification = this.$refs.notification.createNotification( 'Starting password reset', 20, 'progress', 'normal' ); - this.$refs.notification.cancelNotification( startNotification ); - this.$refs.notification.createNotification( 'An account with this email address does not exist.', 5, 'error', 'normal' ); - this.$refs.notification.cancelNotification( startNotification ); - this.$refs.notification.createNotification( 'Password reset email sent. Please follow the instructions given there.', 30, 'ok', '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.createNotification( 'An account with this email address does not exist.', 5, 'error', 'normal' ); + } else { + this.$refs.notification.cancelNotification( startNotification ); + this.$refs.notification.createNotification( 'Password reset email sent. Please follow the instructions given there.', 30, 'ok', 'normal' ); + setTimeout( () => { + location.href = '/login'; + }, 10000 ); + } + } ); } } } diff --git a/src/webapp/main/src/views/user/SignupView.vue b/src/webapp/main/src/views/user/SignupView.vue index f879912..4d85ad2 100644 --- a/src/webapp/main/src/views/user/SignupView.vue +++ b/src/webapp/main/src/views/user/SignupView.vue @@ -46,6 +46,8 @@
+ +