written password reset handler

This commit is contained in:
Henry Oswald 2014-05-15 16:20:23 +01:00
parent f6e85c4140
commit 551e1d465a
6 changed files with 169 additions and 2 deletions

View file

@ -0,0 +1,21 @@
module.exports =
requestPasswordReset: ->
# check user exists
# generate token
# send email token link
renderPasswordResetForm: ->
# check that the token is valid
# render html
changeUsersPasswordFromReset: ->
# check auth again
# check both passwords match
# set passowrd
# redir to login form

View file

@ -0,0 +1,28 @@
settings = require("settings-sharelatex")
async = require("async")
UserGetter = require("../User/UserGetter")
TokenGenerator = require("./TokenGenerator")
EmailHandler = require("../Email/EmailHandler")
AuthenticationManager = require("../Authentication/AuthenticationManager")
module.exports =
generateAndEmailResetToken:(user_id, callback)->
async.series
user: (cb)-> UserGetter.getUser _id:user_id, cb
token: (cb)-> TokenGenerator.getNewToken user_id, cb
, (err, results)->
if err then return callback(err)
if !results.user?
return callback("no user found")
emailOptions =
to : results.user.email
setNewPasswordUrl : "#{settings.siteUrl}/user/password/set?resetToken=#{results.token}"
EmailHandler.sendEmail "passwordResetRequested", emailOptions, callback
setNewUserPassowrd: (token, password, callback)->
TokenGenerator.getUserIdFromToken token, (err, user_id)->
if err then return callback(err)
if !user_id?
return callback("no user found")
AuthenticationManager.setUserPassword user_id, password, callback

View file

@ -0,0 +1,9 @@
module.exports =
apply: (app) ->
app.get '/user/password/reset', PasswordResetController.renderRequestReset
app.post '/user/password/reset', ProjectDownloadsController.requestRest
app.get '/user/password/set', PasswordResetController.renderSetPassword
app.post '/user/password/set', PasswordResetController.setNewUserPassword

View file

@ -34,6 +34,8 @@ FileStoreController = require("./Features/FileStore/FileStoreController")
TrackChangesController = require("./Features/TrackChanges/TrackChangesController")
DropboxUserController = require("./Features/Dropbox/DropboxUserController")
RestoreController = require("./Features/Restore/RestoreController")
PasswordResetRouter = require("./Features/PasswordReset/PasswordResetRouter")
logger = require("logger-sharelatex")
_ = require("underscore")
@ -71,6 +73,7 @@ module.exports = class Router
SubscriptionRouter.apply(app)
UploadsRouter.apply(app)
PasswordResetRouter.apply(app)
if Settings.enableSubscriptions
app.get '/user/bonus', AuthenticationController.requireLogin(), ReferalMiddleware.getUserReferalId, ReferalController.bonus
@ -78,8 +81,7 @@ module.exports = class Router
app.get '/user/settings', AuthenticationController.requireLogin(), UserPagesController.settingsPage
app.post '/user/settings', AuthenticationController.requireLogin(), UserController.updateUserSettings
app.post '/user/password/update', AuthenticationController.requireLogin(), UserController.changePassword
app.get '/user/passwordreset', UserPagesController.passwordResetPage
app.post '/user/passwordReset', UserController.doRequestPasswordReset
app.del '/user/newsletter/unsubscribe', AuthenticationController.requireLogin(), UserController.unsubscribe
app.del '/user', AuthenticationController.requireLogin(), UserController.deleteUser

View file

@ -0,0 +1,31 @@
should = require('chai').should()
SandboxedModule = require('sandboxed-module')
assert = require('assert')
path = require('path')
sinon = require('sinon')
modulePath = path.join __dirname, "../../../../app/js/Features/PasswordReset/PasswordResetController"
expect = require("chai").expect
describe "PasswordResetController", ->
beforeEach ->
@settings = {}
@PasswordResetController = SandboxedModule.require modulePath, requires:
"settings-sharelatex":@settings
"logger-sharelatex": log:->
describe "requestPasswordReset", ->
it "should check the user exists", (done)->
done()
it "should get a unique token and send the email", (done)->
done()

View file

@ -0,0 +1,76 @@
should = require('chai').should()
SandboxedModule = require('sandboxed-module')
assert = require('assert')
path = require('path')
sinon = require('sinon')
modulePath = path.join __dirname, "../../../../app/js/Features/PasswordReset/PasswordResetHandler"
expect = require("chai").expect
describe "PasswordResetHandler", ->
beforeEach ->
@settings =
siteUrl: "www.sharelatex.com"
@TokenGenerator =
getNewToken:sinon.stub()
getUserIdFromToken:sinon.stub()
@UserGetter =
getUser:sinon.stub()
@EmailHandler =
sendEmail:sinon.stub()
@AuthenticationManager =
setUserPassword:sinon.stub()
@PasswordResetHandler = SandboxedModule.require modulePath, requires:
"../User/UserGetter": @UserGetter
"./TokenGenerator": @TokenGenerator
"../Email/EmailHandler":@EmailHandler
"../Authentication/AuthenticationManager":@AuthenticationManager
"settings-sharelatex": @settings
"logger-sharelatex": log:->
@token = "12312321i"
@user_id = "user_id_here"
@user =
email :"bob@bob.com"
@password = "my great secret password"
describe "generateAndEmailResetToken", ->
it "should check the user exists", (done)->
@UserGetter.getUser.callsArgWith(1)
@TokenGenerator.getNewToken.callsArgWith(1)
@PasswordResetHandler.generateAndEmailResetToken @user_id, (err)->
err.should.exists
done()
it "should send the email with the token", (done)->
@UserGetter.getUser.callsArgWith(1, null, @user)
@TokenGenerator.getNewToken.callsArgWith(1, null, @token)
@EmailHandler.sendEmail.callsArgWith(2)
@PasswordResetHandler.generateAndEmailResetToken @user_id, (err)=>
@EmailHandler.sendEmail.called.should.equal true
args = @EmailHandler.sendEmail.args[0]
args[0].should.equal "passwordResetRequested"
args[1].setNewPasswordUrl.should.equal "#{@settings.siteUrl}/user/password/set?resetToken=#{@token}"
done()
describe "setNewUserPassowrd", ->
it "should return err if no user id can be found", (done)->
@TokenGenerator.getUserIdFromToken.callsArgWith(1)
@PasswordResetHandler.setNewUserPassowrd @token, @password, (err)=>
err.should.exists
@AuthenticationManager.setUserPassword.called.should.equal false
done()
it "should set the user password", (done)->
@TokenGenerator.getUserIdFromToken.callsArgWith(1, null, @user_id)
@AuthenticationManager.setUserPassword.callsArgWith(2)
@PasswordResetHandler.setNewUserPassowrd @token, @password, (err)=>
@AuthenticationManager.setUserPassword.calledWith(@user_id, @password).should.equal true
done()