Explorar o código

token based reset works

Henry Oswald %!s(int64=12) %!d(string=hai) anos
pai
achega
96d98329f1

+ 18 - 3
services/web/app/coffee/Features/Email/EmailBuilder.coffee

@@ -37,16 +37,30 @@ Henry <br>
 ShareLaTeX Co-founder
 '''
 
-templates.passwordReset =	
+templates.passwordResetRequested =	
 	subject:  _.template "Password Reset - ShareLatex.com"
 	layout: NotificationEmailLayout
 	type:"notification"
 	compiledTemplate: _.template '''
 <h1 class="h1">Password Reset</h1>
 <p>
-Your password has been reset, the new password is <p> <%= newPassword %>
+We got a request to reset your ShareLaTeX password.
 <p>
-please <a href="https://www.sharelatex.com/login">login here</a> and then change your password <a href=#{Settings.siteUrl}/user/settings> in your user settings</a>
+<center>
+	<div style="width:200px;background-color:#0069CC;border:1px solid #02A9D6;border-radius:4px;padding:15px; margin:10px 5px">
+		<div style="padding-right:10px;padding-left:10px">
+			<a href="<%= setNewPasswordUrl %>" style="text-decoration:none" target="_blank">
+				<span style= "font-size:16px;font-family:Arial;font-weight:bold;color:#fff;white-space:nowrap;display:block; text-align:center">
+		  			Reset password
+				</span>
+			</a>
+		</div>
+	</div>
+</center>
+
+If you ignore this message, your password won't be changed.
+<p>
+If you didn't request a password reset, let us know.
 
 </p>
 <p>Thank you</p>
@@ -79,6 +93,7 @@ module.exports =
 
 	buildEmail: (templateName, opts)->
 		template = templates[templateName]
+		console.log opts
 		opts.body = template.compiledTemplate(opts)
 		return {
 			subject : template.subject(opts)

+ 1 - 1
services/web/app/coffee/Features/PasswordReset/PasswordResetHandler.coffee

@@ -16,7 +16,7 @@ module.exports =
 				if err then return callback(err)
 				emailOptions =
 					to : email
-					setNewPasswordUrl : "#{settings.siteUrl}/user/password/set?resetToken=#{token}"
+					setNewPasswordUrl : "#{settings.siteUrl}/user/password/set?passwordResetToken=#{token}"
 				EmailHandler.sendEmail "passwordResetRequested", emailOptions, callback		
 
 	setNewUserPassword: (token, password, callback)->

+ 7 - 6
services/web/app/coffee/Features/PasswordReset/TokenGenerator.coffee

@@ -4,23 +4,24 @@ rclient = redis.createClient(Settings.redis.web.port, Settings.redis.web.host)
 rclient.auth(Settings.redis.web.password)
 uuid = require("node-uuid")
 
-ONE_MIN = 60 * 1000
-ONE_HOUR_IN_MS = ONE_MIN * 60
+ONE_HOUR_IN_S = 60 * 60
+
+buildKey = (token)-> return "password_token:#{token}"
 
 module.exports =
 
 	getNewToken: (user_id, callback)->
 		token = uuid.v4()
 		multi = rclient.multi()
-		multi.set token, user_id
-		multi.expire token, ONE_HOUR_IN_MS
+		multi.set buildKey(token), user_id
+		multi.expire buildKey(token), ONE_HOUR_IN_S
 		multi.exec (err)->
 			callback(err, token)
 
 	getUserIdFromToken: (token, callback)->
 		multi = rclient.multi()
-		multi.get token
-		multi.del token
+		multi.get buildKey(token)
+		multi.del buildKey(token)
 		multi.exec (err, results)->
 			callback err, results[0]
 

+ 1 - 1
services/web/app/views/user/login.jade

@@ -20,5 +20,5 @@ block content
 							input.span4#password.required(type='password', name='password', placeholder='********')
 					.actions
 						button.btn-primary.btn.btn-large#login(type='submit') Login
-						a#passwordReset(href='/user/passwordreset') forgot password?
+						a#passwordReset(href='/user/password/reset') forgot password?
 	include ../general/small-footer

+ 1 - 1
services/web/app/views/user/setPassword.jade

@@ -7,7 +7,7 @@ block content
 				.page-header
 					h1 Set Password
 				.messageArea
-				form.validate#passwordReset(method='post')
+				form.validate#setPasswordReset(method='post')
 					input(type="hidden", name="_csrf", value=csrfToken)
 					.clearfix
 						label(for='xlInput') Password 

+ 17 - 7
services/web/public/coffee/forms.coffee

@@ -93,16 +93,26 @@ require [
 		event.preventDefault()
 		formData = $(this).serialize()
 		$.ajax
-			url: "/user/passwordReset"
+			url: "/user/password/reset"
 			type:'POST'
 			data: formData
 			success: (data)->
-				if data.message
-					new Message data.message
-				else if data.redir
-					window.location.href = data.redir
-				else
-					window.location.href = '/'
+				new Message text:"You have been sent an email to complete your password reset."
+			error:(data)->
+				new Message type:"error", text:"something went wrong processing your request."
+				
+	$('form#setPasswordReset').submit (event)->
+		event.preventDefault()
+		formData = $(this).serialize()
+		$.ajax
+			url: "/user/password/set"
+			type:'POST'
+			data: formData
+			success: (data)->
+				new Message text:"Your password has been reset"
+			error:(data)->
+				new Message type:"error", text:"something went wrong processing your request."
+
 
 
 	$('a#deleteUserAccount').click (e)->

+ 1 - 1
services/web/test/UnitTests/coffee/PasswordReset/PasswordResetHandlerTests.coffee

@@ -54,7 +54,7 @@ describe "PasswordResetHandler", ->
 				@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}"
+				args[1].setNewPasswordUrl.should.equal "#{@settings.siteUrl}/user/password/set?passwordResetToken=#{@token}"
 				done()
 
 

+ 4 - 4
services/web/test/UnitTests/coffee/PasswordReset/TokenGeneratorTests.coffee

@@ -39,8 +39,8 @@ describe "TokenGenerator", ->
 		it "should set a new token into redis with a ttl", (done)->
 			@redisMulti.exec.callsArgWith(0) 
 			@TokenGenerator.getNewToken @user_id, (err, token)=>
-				@redisMulti.set @stubbedToken, @user_id
-				@redisMulti.expire @stubbedToken, (60*1000)*60
+				@redisMulti.set "password_token:#{@stubbedToken}", @user_id
+				@redisMulti.expire "password_token:#{@stubbedToken}", 60 * 60
 				done()
 
 		it "should return if there was an error", (done)->
@@ -56,8 +56,8 @@ describe "TokenGenerator", ->
 			@redisMulti.exec.callsArgWith(0, null, [@user_id]) 
 			@TokenGenerator.getUserIdFromToken @stubbedToken, (err, user_id)=>
 				user_id.should.equal @user_id
-				@redisMulti.get.calledWith(@stubbedToken).should.equal true
-				@redisMulti.del.calledWith(@stubbedToken).should.equal true
+				@redisMulti.get.calledWith("password_token:#{@stubbedToken}").should.equal true
+				@redisMulti.del.calledWith("password_token:#{@stubbedToken}").should.equal true
 				done()