endpoints for updating password

This commit is contained in:
Riley Davis
2016-11-16 11:49:58 -07:00
parent c86e1e8d47
commit 7df7279323
3 changed files with 65 additions and 14 deletions
+39 -3
View File
@@ -196,6 +196,7 @@ UserSchema.statics.changePassword = function(id, password) {
})
.then((hashedPassword) => {
return User.update({id}, {
$inc: {__v: 1},
$set: {
password: hashedPassword
}
@@ -346,6 +347,10 @@ UserSchema.statics.findByIdArray = function(ids) {
});
};
/**
* Creates a JWT from a user email. Only works for local accounts.
* @param {String} email of the local user
*/
UserSchema.statics.createJWT = function (email) {
if (!email || typeof email !== 'string') {
return Promise.reject('email is required when creating a JWT for resetting passord');
@@ -353,11 +358,42 @@ UserSchema.statics.createJWT = function (email) {
email = email.toLowerCase();
const payload = {email, jti: uuid.v4()};
return this.findOne({profiles: {$elemMatch: {id: email}}})
.then(user => {
const token = jwt.sign(payload, process.env.TALK_SESSION_SECRET, {expiresIn: '1d'});
if (user === null) {
return Promise.reject(`Uh oh! We've never heard of ${email}. Maybe there's a typo in there?`);
}
return Promise.resolve(token);
const payload = {email, jti: uuid.v4(), userId: user.id, version: user.__v};
const token = jwt.sign(payload, process.env.TALK_SESSION_SECRET, {expiresIn: '1d'});
return token;
});
};
/**
* verifies a jwt and returns the associated user
* @param {String} token the JSON Web Token to verify
*/
UserSchema.statics.verifyToken = function (token) {
return new Promise((resolve, reject) => {
jwt.verify(token, process.env.TALK_SESSION_SECRET, (error, decoded) => {
if (error) {
return reject(error);
}
resolve(decoded);
});
})
.then(decoded => {
/**
* TODO: check the jti from this decoded token in redis
* and make an entry if it does not exist.
* reject if entry already exists.
*/
return this.findOne({id: decoded.userId});
});
};
const User = mongoose.model('User', UserSchema);
+2 -10
View File
@@ -1,5 +1,4 @@
const express = require('express');
const jwt = require('jsonwebtoken');
const router = express.Router();
router.get('/embed/stream/preview', (req, res) => {
@@ -7,15 +6,8 @@ router.get('/embed/stream/preview', (req, res) => {
});
router.get('/password-reset/:token', (req, res, next) => {
jwt.verify(req.params.token, process.env.TALK_SESSION_SECRET, (error, decoded) => {
if (error) {
return res.status(400).json({error});
}
console.log(decoded);
res.json(decoded);
});
// render a page or something?
res.send('ok');
});
router.get('*', (req, res) => {
+24 -1
View File
@@ -71,6 +71,27 @@ router.post('/:user_id/role', (req, res, next) => {
.catch(next);
});
/**
* expects 2 fields in the body of the request
* 1) the token that was in the url of the email link {String}
* 2) the new password {String}
*/
router.post('/update-password', (req, res, next) => {
const {token, password} = req.body;
User.verifyToken(token)
.then(user => {
return User.changePassword(user.id, password);
})
.then(() => {
res.status(204).end();
})
.catch(error => {
console.error(error);
res.status(401).send('Not Authorized');
});
});
/**
* this endpoint takes an email (username) and checks if it belongs to a User account
* if it does, create a JWT and send an email
@@ -91,7 +112,9 @@ router.post('/request-password-reset', (req, res, next) => {
subject: 'password reset requested',
from: 'coralcore@mozillafoundation.org',
to: 'riley.davis@gmail.com',
html: `<a href="http://localhost:3000/admin/password-reset/${token}">reset password</a>`
html: `<p>We received a request to reset your password. If you did not request this change, you can ignore this email.
If you did, <a href="http://localhost:3000/admin/password-reset/${token}">please click here to reset password</a>.</p>
${process.env.NODE_ENV === 'production' ? '' : `<h1>${token}</h1>`}`
};
return mailer.sendSimple(options);
})