Skip to content

Commit 56f8a0a

Browse files
committed
Create project
-First commit
0 parents  commit 56f8a0a

File tree

3,886 files changed

+536914
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

3,886 files changed

+536914
-0
lines changed

app.js

Lines changed: 285 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
var express = require('express');
2+
var path = require('path');
3+
var favicon = require('serve-favicon');
4+
var logger = require('morgan');
5+
var cookieParser = require('cookie-parser');
6+
var bodyParser = require('body-parser');
7+
var session = require('express-session')
8+
var mongoose = require('mongoose');
9+
var nodemailer = require('nodemailer');
10+
var sendgridTransport = require('nodemailer-sendgrid-transport');
11+
var passport = require('passport');
12+
var LocalStrategy = require('passport-local').Strategy;
13+
var bcrypt = require('bcrypt-nodejs');
14+
var async = require('async');
15+
var crypto = require('crypto');
16+
var flash = require('express-flash');
17+
18+
// Mongoose Function
19+
var userSchema = new mongoose.Schema({
20+
username: { type: String, required: true, unique: true },
21+
email: { type: String, required: true, unique: true },
22+
password: { type: String, required: true },
23+
resetPasswordToken: String,
24+
resetPasswordExpires: Date
25+
});
26+
27+
userSchema.pre('save', function(next) {
28+
var user = this;
29+
var SALT_FACTOR = 5;
30+
31+
if (!user.isModified('password')) return next();
32+
33+
bcrypt.genSalt(SALT_FACTOR, function(err, salt) {
34+
if (err) return next(err);
35+
36+
bcrypt.hash(user.password, salt, null, function(err, hash) {
37+
if (err) return next(err);
38+
user.password = hash;
39+
next();
40+
});
41+
});
42+
});
43+
44+
userSchema.methods.comparePassword = function(candidatePassword, cb) {
45+
bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
46+
if (err) return cb(err);
47+
cb(null, isMatch);
48+
});
49+
};
50+
51+
var User = mongoose.model('User', userSchema);
52+
mongoose.connect('mongodb://localhost:27017');
53+
54+
// Passport Function
55+
passport.use(new LocalStrategy(function(username, password, done) {
56+
User.findOne({ username: username }, function(err, user) {
57+
if (err) return done(err);
58+
if (!user) return done(null, false, { message: 'Incorrect username.' });
59+
user.comparePassword(password, function(err, isMatch) {
60+
if (isMatch) {
61+
return done(null, user);
62+
} else {
63+
return done(null, false, { message: 'Incorrect password.' });
64+
}
65+
});
66+
});
67+
}));
68+
69+
passport.serializeUser(function(user, done) {
70+
done(null, user.id);
71+
});
72+
73+
passport.deserializeUser(function(id, done) {
74+
User.findById(id, function(err, user) {
75+
done(err, user);
76+
});
77+
});
78+
79+
// App
80+
var app = express();
81+
82+
// Middleware
83+
app.set('port', process.env.PORT || 3000);
84+
app.set('views', path.join(__dirname, 'views'));
85+
app.set('view engine', 'jade');
86+
app.use(favicon(__dirname + '/public/images/favicon.ico'));
87+
app.use(logger('dev'));
88+
app.use(bodyParser.json());
89+
app.use(bodyParser.urlencoded());
90+
app.use(cookieParser());
91+
app.use(session({ secret: 'session secret key' }));
92+
app.use(flash());
93+
app.use(passport.initialize());
94+
app.use(passport.session());
95+
app.use(express.static(path.join(__dirname, 'public')));
96+
97+
// Routes
98+
app.get('/', function(req, res){
99+
res.render('index', {
100+
title: 'Express',
101+
user: req.user
102+
});
103+
});
104+
105+
app.get('/login', function(req, res) {
106+
res.render('login', {
107+
user: req.user
108+
});
109+
});
110+
111+
app.post('/login', function(req, res, next) {
112+
passport.authenticate('local', function(err, user, info) {
113+
if (err) return next(err)
114+
if (!user) {
115+
return res.redirect('/login')
116+
}
117+
req.logIn(user, function(err) {
118+
if (err) return next(err);
119+
return res.redirect('/');
120+
});
121+
})(req, res, next);
122+
});
123+
124+
app.get('/signup', function(req, res) {
125+
res.render('signup', {
126+
user: req.user
127+
});
128+
});
129+
130+
app.post('/signup', function(req, res) {
131+
var user = new User({
132+
username: req.body.username,
133+
email: req.body.email,
134+
password: req.body.password
135+
});
136+
137+
user.save(function(err) {
138+
req.logIn(user, function(err) {
139+
res.redirect('/');
140+
});
141+
});
142+
});
143+
144+
app.get('/logout', function(req, res){
145+
req.logout();
146+
res.redirect('/');
147+
});
148+
149+
app.get('/forgot', function(req, res) {
150+
res.render('forgot', {
151+
user: req.user
152+
});
153+
});
154+
155+
app.post('/forgot', function(req, res, next) {
156+
async.waterfall([
157+
function(done) {
158+
crypto.randomBytes(20, function(err, buf) {
159+
var token = buf.toString('hex');
160+
done(err, token);
161+
});
162+
},
163+
function(token, done) {
164+
User.findOne({ email: req.body.email }, function(err, user) {
165+
if (!user) {
166+
req.flash('error', 'No account with that email address exists.');
167+
return res.redirect('/forgot');
168+
}
169+
170+
user.resetPasswordToken = token;
171+
user.resetPasswordExpires = Date.now() + 3600000; // 1 hour
172+
173+
user.save(function(err) {
174+
done(err, token, user);
175+
});
176+
});
177+
},
178+
function(token, user, done) {
179+
var smtpTransport = nodemailer.createTransport(
180+
sendgridTransport({
181+
auth: {
182+
api_user: "username", // SendGrid Username
183+
api_key: "password", // SendGrid Password
184+
},
185+
})
186+
);
187+
188+
// Email Details
189+
var mailOptions = {
190+
to: user.email,
191+
192+
subject: 'Express.js Password Reset',
193+
text: 'You are receiving this because you (or someone else) have requested the reset of the password for your account.\n\n' +
194+
'Please click on the following link, or paste this into your browser to complete the process:\n\n' +
195+
'http://' + req.headers.host + '/reset/' + token + '\n\n' +
196+
'If you did not request this, please ignore this email and your password will remain unchanged.\n'
197+
};
198+
199+
// Send Email
200+
smtpTransport.sendMail(mailOptions, (err, resp) => {
201+
if (err) {
202+
// handle error
203+
} else {
204+
// handle success
205+
req.flash('info', 'An e-mail has been sent to ' + user.email + ' with further instructions.');
206+
done(err, 'done');
207+
}
208+
});
209+
}
210+
], function(err) {
211+
if (err) return next(err);
212+
res.redirect('/forgot');
213+
});
214+
});
215+
216+
app.get('/reset/:token', function(req, res) {
217+
User.findOne({ resetPasswordToken: req.params.token, resetPasswordExpires: { $gt: Date.now() } }, function(err, user) {
218+
if (!user) {
219+
req.flash('error', 'Password reset token is invalid or has expired.');
220+
return res.redirect('/forgot');
221+
}
222+
res.render('reset', {
223+
user: req.user
224+
});
225+
});
226+
});
227+
228+
app.post('/reset/:token', function(req, res) {
229+
async.waterfall([
230+
function(done) {
231+
User.findOne({ resetPasswordToken: req.params.token, resetPasswordExpires: { $gt: Date.now() } }, function(err, user) {
232+
if (!user) {
233+
req.flash('error', 'Password reset token is invalid or has expired.');
234+
return res.redirect('back');
235+
}
236+
237+
user.password = req.body.password;
238+
user.resetPasswordToken = undefined;
239+
user.resetPasswordExpires = undefined;
240+
241+
user.save(function(err) {
242+
req.logIn(user, function(err) {
243+
done(err, user);
244+
});
245+
});
246+
});
247+
},
248+
function(user, done) {
249+
var smtpTransport = nodemailer.createTransport(
250+
sendgridTransport({
251+
auth: {
252+
api_user: "username", // SendGrid Username
253+
api_key: "password", // SendGrid Password
254+
},
255+
})
256+
);
257+
258+
// Email Details
259+
var mailOptions = {
260+
to: user.email,
261+
262+
subject: 'Your password has been changed',
263+
text: 'Hello,\n\n' +
264+
'This is a confirmation that the password for your account ' + user.email + ' has just been changed.\n'
265+
};
266+
267+
// Send Email
268+
smtpTransport.sendMail(mailOptions, (err, resp) => {
269+
if (err) {
270+
// handle error
271+
} else {
272+
// handle success
273+
req.flash('success', 'Success! Your password has been changed.');
274+
done(err);
275+
}
276+
});
277+
}
278+
], function(err) {
279+
res.redirect('/');
280+
});
281+
});
282+
283+
app.listen(app.get('port'), function() {
284+
console.log('Express server listening on port ' + app.get('port'));
285+
});

node_modules/.bin/acorn

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/cleancss

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/jade

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/mime

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/mkdirp

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/semver

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/sshpk-conv

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/sshpk-sign

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node_modules/.bin/sshpk-verify

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)