aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Wilkins <samwilkins333@gmail.com>2019-02-25 03:38:02 -0500
committerSam Wilkins <samwilkins333@gmail.com>2019-02-25 03:38:02 -0500
commit0d36924c90682c57e96c1e7bfd95a3cc10e6c662 (patch)
tree483d5ee1c3ef0d7bffc90f6d631bf3cea2256ff0
parent47152d960e5b79f395fb4ecc421e5aac0c12883e (diff)
after pop, hard reset
-rw-r--r--src/client/views/Main.tsx6
-rw-r--r--src/server/authentication/controllers/user.ts135
-rw-r--r--src/server/authentication/models/User.ts4
-rw-r--r--src/server/index.ts68
-rw-r--r--views/reset.pug22
-rw-r--r--views/signup.pug2
-rw-r--r--views/stylesheets/authentication.css6
7 files changed, 176 insertions, 67 deletions
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index cbc19d7fe..567f17752 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -171,6 +171,12 @@ function init() {
right: '0px',
width: '150px'
}} onClick={() => UndoManager.Redo()}>Redo</button>
+ <button style={{
+ position: 'absolute',
+ top: '24px',
+ right: '0px',
+ width: '150px'
+ }} onClick={() => window.location.pathname = "/logout"}>Logout</button>
</div>),
document.getElementById('root'));
})
diff --git a/src/server/authentication/controllers/user.ts b/src/server/authentication/controllers/user.ts
index a496959d1..19cd09676 100644
--- a/src/server/authentication/controllers/user.ts
+++ b/src/server/authentication/controllers/user.ts
@@ -7,6 +7,10 @@ import * as request from "express-validator";
const flash = require("express-flash");
import * as session from "express-session";
import * as pug from 'pug';
+import * as async from 'async';
+import * as nodemailer from 'nodemailer';
+import c = require("crypto");
+
/**
* GET /
@@ -46,8 +50,6 @@ export let postSignup = (req: Request, res: Response, next: NextFunction) => {
req.assert("confirmPassword", "Passwords do not match").equals(req.body.password);
req.sanitize("email").normalizeEmail({ gmail_remove_dots: false });
- req.flash("Working on something!!!");
-
const errors = req.validationErrors();
if (errors) {
@@ -146,4 +148,133 @@ export let getLogout = (req: Request, res: Response) => {
sess.destroy((err) => { if (err) { console.log(err); } });
}
res.redirect('/login');
+}
+
+export let getForgot = function (req: Request, res: Response) {
+ res.render("forgot.pug", {
+ title: "Recover Password",
+ user: req.user,
+ });
+}
+
+export let postForgot = function (req: Request, res: Response, next: NextFunction) {
+ const email = req.body.email;
+ async.waterfall([
+ function (done: any) {
+ let token: string;
+ c.randomBytes(20, function (err: any, buffer: Buffer) {
+ if (err) {
+ done(null);
+ return;
+ }
+ done(null, buffer.toString('hex'));
+ })
+ },
+ function (token: Buffer, done: any) {
+ User.findOne({ email }, function (err, user: UserModel) {
+ if (!user) {
+ // NO ACCOUNT WITH SUBMITTED EMAIL
+ return res.redirect('/forgot');
+ }
+ user.passwordResetToken = token.toString('utf8');
+ console.log(user.passwordResetToken);
+ user.passwordResetExpires = new Date(Date.now() + 3600000); // 1 HOUR
+ user.save(function (err: any) {
+ done(null, token, user);
+ });
+ });
+ },
+ function (token: Uint16Array, user: UserModel, done: any) {
+ const smtpTransport = nodemailer.createTransport({
+ service: 'Gmail',
+ auth: {
+ user: 'brownptcdash@gmail.com',
+ pass: 'browngfx1'
+ }
+ });
+ const mailOptions = {
+ to: user.email,
+ from: 'brownptcdash@gmail.com',
+ subject: 'Dash Password Reset',
+ text: 'You are receiving this because you (or someone else) have requested the reset of the password for your account.\n\n' +
+ 'Please click on the following link, or paste this into your browser to complete the process:\n\n' +
+ 'http://' + req.headers.host + '/reset/' + token + '\n\n' +
+ 'If you did not request this, please ignore this email and your password will remain unchanged.\n'
+ };
+ smtpTransport.sendMail(mailOptions, function (err) {
+ // req.flash('info', 'An e-mail has been sent to ' + user.email + ' with further instructions.');
+ done(null, err, 'done');
+ });
+ }
+ ], function (err) {
+ if (err) return next(err);
+ res.redirect('/forgot');
+ })
+}
+
+export let getReset = function (req: Request, res: Response) {
+ User.findOne({ passwordResetToken: req.params.token, passwordResetExpires: { $gt: Date.now() } }, function (err, user: UserModel) {
+ if (!user || err) {
+ return res.redirect('/forgot');
+ }
+ res.render("reset.pug", {
+ title: "Reset Password",
+ user: req.user,
+ });
+ });
+}
+
+export let postReset = function (req: Request, res: Response) {
+ async.waterfall([
+ function (done: any) {
+ User.findOne({ passwordResetToken: req.params.token, passwordResetExpires: { $gt: Date.now() } }, function (err, user: UserModel) {
+ if (!user || err) {
+ return res.redirect('back');
+ }
+
+ req.assert("password", "Password must be at least 4 characters long").len({ min: 4 });
+ req.assert("confirmPassword", "Passwords do not match").equals(req.body.password);
+
+ if (req.validationErrors()) {
+ return res.redirect('back');
+ }
+
+ user.password = req.body.password;
+ user.passwordResetToken = undefined;
+ user.passwordResetExpires = undefined;
+
+ user.save(function (err) {
+ req.logIn(user, function (err) {
+ if (err) {
+ console.log(err);
+ return;
+ }
+ });
+ done(user, err);
+ });
+ });
+ },
+ function (user: UserModel, done: any) {
+ console.log(`SENDING EMAIL TO ${user.email}`);
+ const smtpTransport = nodemailer.createTransport({
+ service: 'Gmail',
+ auth: {
+ user: 'brownptcdash@gmail.com',
+ pass: 'browngfx1'
+ }
+ });
+ const mailOptions = {
+ to: user.email,
+ from: 'brownptcdash@gmail.com',
+ subject: 'Your password has been changed',
+ text: 'Hello,\n\n' +
+ 'This is a confirmation that the password for your account ' + user.email + ' has just been changed.\n'
+ };
+ smtpTransport.sendMail(mailOptions, function (err) {
+ done(null, err);
+ });
+ }
+ ], function (err) {
+ res.redirect('/login');
+ });
} \ No newline at end of file
diff --git a/src/server/authentication/models/User.ts b/src/server/authentication/models/User.ts
index 30fcecd81..433e2f6c3 100644
--- a/src/server/authentication/models/User.ts
+++ b/src/server/authentication/models/User.ts
@@ -18,8 +18,8 @@ mongoose.connection.on('disconnected', function () {
export type UserModel = mongoose.Document & {
email: string,
password: string,
- passwordResetToken: string,
- passwordResetExpires: Date,
+ passwordResetToken: string | undefined,
+ passwordResetExpires: Date | undefined,
tokens: AuthToken[],
profile: {
diff --git a/src/server/index.ts b/src/server/index.ts
index baf360ffa..f2b26afec 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -17,7 +17,7 @@ import * as bcrypt from "bcrypt-nodejs";
import { Document } from '../fields/Document';
import * as io from 'socket.io'
import * as passportConfig from './authentication/config/passport';
-import { getLogin, postLogin, getSignup, postSignup, getLogout, getEntry } from './authentication/controllers/user';
+import { getLogin, postLogin, getSignup, postSignup, getLogout, getEntry, postReset, getForgot, postForgot, getReset } from './authentication/controllers/user';
const config = require('../../webpack.config');
const compiler = webpack(config);
const port = 1050; // default port to listen
@@ -28,11 +28,9 @@ import flash = require('express-flash');
import * as bodyParser from 'body-parser';
import * as session from 'express-session';
import * as cookieParser from 'cookie-parser';
-import * as nodemailer from 'nodemailer';
import c = require("crypto");
const MongoStore = require('connect-mongo')(session);
const mongoose = require('mongoose');
-import * as async from 'async';
const bluebird = require('bluebird');
import { performance } from 'perf_hooks'
import * as path from 'path'
@@ -88,7 +86,6 @@ app.get("/home", (req, res) => {
});
app.get("/getUserDocId", (req, res) => {
- console.log(req.user)
if (!req.user) {
return;
}
@@ -119,64 +116,15 @@ app.get('/logout', getLogout);
// ***
-app.get('/forgot', function (req, res) {
- res.render("forgot.pug", {
- title: "Recover Password",
- user: req.user,
- });
-})
-
// FORGOT PASSWORD EMAIL HANDLING
-app.post('/forgot', function (req, res, next) {
- const email = req.body.email;
- async.waterfall([
- function (done: any) {
- const seed = new Uint32Array(20);
- let token = seed;
- done(null, token);
- },
- function (token: Uint32Array, done: any) {
- User.findOne({ email }, function (err, user: UserModel) {
- if (!user) {
- // NO ACCOUNT WITH SUBMITTED EMAIL
- return res.redirect('/forgot');
- }
- user.passwordResetToken = token.toString();
- user.passwordResetExpires = new Date(Date.now() + 3600000); // 1 HOUR
- user.save(function (err: any) {
- done(null, token, user);
- });
- });
- },
- function (token: Uint16Array, user: UserModel, done: any) {
- const smptTransport = nodemailer.createTransport({
- service: 'Gmail',
- auth: {
- user: 'brownptcdash@gmail.com',
- pass: 'browngfx1'
- }
- });
- const mailOptions = {
- to: user.email,
- from: 'brownptcdash@gmail.com',
- subject: 'Dash Password Reset',
- text: 'You are receiving this because you (or someone else) have requested the reset of the password for your account.\n\n' +
- 'Please click on the following link, or paste this into your browser to complete the process:\n\n' +
- 'http://' + req.headers.host + '/reset/' + token + '\n\n' +
- 'If you did not request this, please ignore this email and your password will remain unchanged.\n'
- };
- smptTransport.sendMail(mailOptions, function (err) {
- // req.flash('info', 'An e-mail has been sent to ' + user.email + ' with further instructions.');
- done(null, err, 'done');
- });
- }
- ], function (err) {
- if (err) return next(err);
- res.redirect('/forgot');
- })
-})
-let FieldStore: ObservableMap<FieldId, Field> = new ObservableMap();
+app.get('/forgot', getForgot)
+app.post('/forgot', postForgot)
+// RESET PASSWORD EMAIL HANDLING
+app.get('/reset/:token', getReset);
+app.post('/reset/:token', postReset);
+
+let FieldStore: ObservableMap<FieldId, Field> = new ObservableMap();
app.get("/hello", (req, res) => {
res.send("<p>Hello</p>");
})
diff --git a/views/reset.pug b/views/reset.pug
new file mode 100644
index 000000000..8b6fa952b
--- /dev/null
+++ b/views/reset.pug
@@ -0,0 +1,22 @@
+
+extends ./layout
+
+block content
+ style
+ include ./stylesheets/authentication.css
+ form.form-horizontal(id='reset-form', method='POST')
+ input(type='hidden', name='_csrf', value=_csrf)
+ .overlay(id='overlay_reset')
+ .inner.reset
+ h3.auth_header Reset Password
+ .form-group
+ .col-sm-7
+ input.form-control(type='password', name='password', id='password', placeholder='Password', required)
+ .form-group
+ .col-sm-7
+ input.form-control(type='password', name='confirmPassword', id='confirmPassword', placeholder='Confirm Password', required)
+ .form-group
+ .col-sm-offset-3.col-sm-7
+ button.btn.btn-success(type='submit')
+ i.fa.fa-user-plus
+ | Reset \ No newline at end of file
diff --git a/views/signup.pug b/views/signup.pug
index 374710e6f..11b02a5eb 100644
--- a/views/signup.pug
+++ b/views/signup.pug
@@ -24,4 +24,4 @@ block content
.col-sm-offset-3.col-sm-7
button.btn.btn-success(type='submit')
i.fa.fa-user-plus
- | Signup \ No newline at end of file
+ | Sign Up \ No newline at end of file
diff --git a/views/stylesheets/authentication.css b/views/stylesheets/authentication.css
index 0922ad730..bce8223ec 100644
--- a/views/stylesheets/authentication.css
+++ b/views/stylesheets/authentication.css
@@ -26,7 +26,8 @@ body {
text-align: left;
}
-.login {
+.login,
+.reset {
height: 220px;
}
@@ -46,7 +47,8 @@ body {
font-style: oblique;
}
-#overlay_signup {
+#overlay_signup,
+#overlay_reset {
height: 345px;
}