Shane Kilkelly 10 лет назад
Родитель
Сommit
ab2c1e82fb
22 измененных файлов с 394 добавлено и 361 удалено
  1. 2 2
      services/web/app/coffee/Features/Analytics/AnalyticsController.coffee
  2. 75 64
      services/web/app/coffee/Features/Authentication/AuthenticationController.coffee
  3. 12 15
      services/web/app/coffee/Features/Authorization/AuthorizationMiddlewear.coffee
  4. 6 2
      services/web/app/coffee/Features/Chat/ChatController.coffee
  5. 66 61
      services/web/app/coffee/Features/Collaborators/CollaboratorsInviteController.coffee
  6. 31 31
      services/web/app/coffee/Features/Compile/CompileController.coffee
  7. 22 23
      services/web/app/coffee/Features/Contacts/ContactController.coffee
  8. 5 3
      services/web/app/coffee/Features/Notifications/NotificationsController.coffee
  9. 64 59
      services/web/app/coffee/Features/Project/ProjectController.coffee
  10. 4 2
      services/web/app/coffee/Features/Referal/ReferalController.coffee
  11. 4 3
      services/web/app/coffee/Features/Referal/ReferalMiddleware.coffee
  12. 6 8
      services/web/app/coffee/Features/Security/RateLimiterMiddlewear.coffee
  13. 3 1
      services/web/app/coffee/Features/Spelling/SpellingController.coffee
  14. 3 2
      services/web/app/coffee/Features/StaticPages/HomeController.coffee
  15. 2 2
      services/web/app/coffee/Features/Subscription/SubscriptionController.coffee
  16. 22 18
      services/web/app/coffee/Features/Subscription/SubscriptionGroupController.coffee
  17. 12 11
      services/web/app/coffee/Features/Tags/TagsController.coffee
  18. 13 14
      services/web/app/coffee/Features/TrackChanges/TrackChangesController.coffee
  19. 4 6
      services/web/app/coffee/Features/Uploads/ProjectUploadController.coffee
  20. 17 14
      services/web/app/coffee/Features/User/UserController.coffee
  21. 6 4
      services/web/app/coffee/Features/User/UserPagesController.coffee
  22. 15 16
      services/web/app/coffee/infrastructure/ExpressLocals.coffee

+ 2 - 2
services/web/app/coffee/Features/Analytics/AnalyticsController.coffee

@@ -1,7 +1,7 @@
-AnalyticsManager = require "./AnalyticsManager"
+AnalyticsManager = equire "./AnalyticsManager"
 
 
 module.exports = AnalyticsController =
 module.exports = AnalyticsController =
 	recordEvent: (req, res, next) ->
 	recordEvent: (req, res, next) ->
 		AnalyticsManager.recordEvent req.session?.user?._id, req.params.event, req.body, (error) ->
 		AnalyticsManager.recordEvent req.session?.user?._id, req.params.event, req.body, (error) ->
 			return next(error) if error?
 			return next(error) if error?
-			res.send 204
+			res.send 204

+ 75 - 64
services/web/app/coffee/Features/Authentication/AuthenticationController.coffee

@@ -14,8 +14,8 @@ Analytics = require "../Analytics/AnalyticsManager"
 
 
 module.exports = AuthenticationController =
 module.exports = AuthenticationController =
 
 
-	login: (req, res, next = (error) ->) ->
-		AuthenticationController.doLogin req.body, req, res, next
+	# login: (req, res, next = (error) ->) ->
+	# 	AuthenticationController.doLogin req.body, req, res, next
 
 
 	serializeUser: (user, callback) ->
 	serializeUser: (user, callback) ->
 		console.log ">> serialize", user._id
 		console.log ">> serialize", user._id
@@ -65,60 +65,38 @@ module.exports = AuthenticationController =
 					logger.log email: email, "failed log in"
 					logger.log email: email, "failed log in"
 					return done(null, false, {message: req.i18n.translate("email_or_password_wrong_try_again"), type: 'error'})
 					return done(null, false, {message: req.i18n.translate("email_or_password_wrong_try_again"), type: 'error'})
 
 
+	isUserLoggedIn: (req) ->
+		user_id = AuthenticationController.getLoggedInUserId(req)
+		return user_id?
 
 
-	doLogin: (options, req, res, next) ->
-		dienow
-		email = options.email?.toLowerCase()
-		password = options.password
-		redir = Url.parse(options.redir or "/project").path
-		LoginRateLimiter.processLoginRequest email, (err, isAllowed)->
-			if !isAllowed
-				logger.log email:email, "too many login requests"
-				res.statusCode = 429
-				return res.send
-					message:
-						text: req.i18n.translate("to_many_login_requests_2_mins"),
-						type: 'error'
-			AuthenticationManager.authenticate email: email, password, (error, user) ->
-				return next(error) if error?
-				if user?
-					UserHandler.setupLoginData user, ->
-					LoginRateLimiter.recordSuccessfulLogin email
-					AuthenticationController._recordSuccessfulLogin user._id
-					AuthenticationController.establishUserSession req, user, (error) ->
-						return next(error) if error?
-						req.session.justLoggedIn = true
-						logger.log email: email, user_id: user._id.toString(), "successful log in"
-						Analytics.recordEvent user._id, "user-logged-in"
-						res.json redir: redir
-				else
-					AuthenticationController._recordFailedLogin()
-					logger.log email: email, "failed log in"
-					res.json message:
-						text: req.i18n.translate("email_or_password_wrong_try_again"),
-						type: 'error'
-
-	getLoggedInUserId: (req, callback = (error, user_id) ->) ->
+	# TODO: perhaps should produce an error if the current user is not present
+	getLoggedInUserId: (req) ->
+		# old sessions
 		if req?.session?.user?._id?
 		if req?.session?.user?._id?
-			callback null, req.session.user._id.toString()
+			return req.session.user._id.toString()
+		# new passport sessions
+		else if req?.session?.passport?.user?._id?
+			return req.session.passport.user._id.toString()
+		# neither
 		else
 		else
-			callback null, null
+			return null
 
 
+	# TODO: perhaps should produce an error if the current user is not present
 	getLoggedInUser: (req, callback = (error, user) ->) ->
 	getLoggedInUser: (req, callback = (error, user) ->) ->
 		if req.session?.user?._id?
 		if req.session?.user?._id?
 			query = req.session.user._id
 			query = req.session.user._id
 		else
 		else
 			return callback null, null
 			return callback null, null
 
 
-		UserGetter.getUser query, callback
+		# omit sensitive information
+		UserGetter.getUser query, {hashedPassword: false, refProviders: false}, callback
 
 
 	requireLogin: () ->
 	requireLogin: () ->
 		doRequest = (req, res, next = (error) ->) ->
 		doRequest = (req, res, next = (error) ->) ->
 			console.log ">>>>", req.currentUser()
 			console.log ">>>>", req.currentUser()
-			if !req.session.user?
+			if !AuthenticationController.isUserLoggedIn()?
 				AuthenticationController._redirectToLoginOrRegisterPage(req, res)
 				AuthenticationController._redirectToLoginOrRegisterPage(req, res)
 			else
 			else
-				req.user = req.session.user
 				return next()
 				return next()
 
 
 		return doRequest
 		return doRequest
@@ -133,7 +111,7 @@ module.exports = AuthenticationController =
 
 
 		if req.headers['authorization']?
 		if req.headers['authorization']?
 			return AuthenticationController.httpAuth(req, res, next)
 			return AuthenticationController.httpAuth(req, res, next)
-		else if req.session.user?
+		else if AuthenticationController.isUserLoggedIn()?
 			return next()
 			return next()
 		else
 		else
 			logger.log url:req.url, "user trying to access endpoint not in global whitelist"
 			logger.log url:req.url, "user trying to access endpoint not in global whitelist"
@@ -179,26 +157,59 @@ module.exports = AuthenticationController =
 		Metrics.inc "user.login.failed"
 		Metrics.inc "user.login.failed"
 		callback()
 		callback()
 
 
-	establishUserSession: (req, user, callback = (error) ->) ->
-		dienow
-		lightUser =
-			_id: user._id
-			first_name: user.first_name
-			last_name: user.last_name
-			isAdmin: user.isAdmin
-			email: user.email
-			referal_id: user.referal_id
-			session_created: (new Date()).toISOString()
-			ip_address: req.ip
-		# Regenerate the session to get a new sessionID (cookie value) to
-		# protect against session fixation attacks
-		oldSession = req.session
-		req.session.destroy()
-		req.sessionStore.generate(req)
-		for key, value of oldSession
-			req.session[key] = value
-
-		req.session.user = lightUser
-
-		UserSessionsManager.trackSession(user, req.sessionID, () ->)
-		callback()
+	# establishUserSession: (req, user, callback = (error) ->) ->
+	# 	dienow
+	# 	lightUser =
+	# 		_id: user._id
+	# 		first_name: user.first_name
+	# 		last_name: user.last_name
+	# 		isAdmin: user.isAdmin
+	# 		email: user.email
+	# 		referal_id: user.referal_id
+	# 		session_created: (new Date()).toISOString()
+	# 		ip_address: req.ip
+	# 	# Regenerate the session to get a new sessionID (cookie value) to
+	# 	# protect against session fixation attacks
+	# 	oldSession = req.session
+	# 	req.session.destroy()
+	# 	req.sessionStore.generate(req)
+	# 	for key, value of oldSession
+	# 		req.session[key] = value
+
+	# 	req.session.user = lightUser
+
+	# 	UserSessionsManager.trackSession(user, req.sessionID, () ->)
+	# 	callback()
+
+
+	# doLogin: (options, req, res, next) ->
+	# 	dienow
+	# 	email = options.email?.toLowerCase()
+	# 	password = options.password
+	# 	redir = Url.parse(options.redir or "/project").path
+	# 	LoginRateLimiter.processLoginRequest email, (err, isAllowed)->
+	# 		if !isAllowed
+	# 			logger.log email:email, "too many login requests"
+	# 			res.statusCode = 429
+	# 			return res.send
+	# 				message:
+	# 					text: req.i18n.translate("to_many_login_requests_2_mins"),
+	# 					type: 'error'
+	# 		AuthenticationManager.authenticate email: email, password, (error, user) ->
+	# 			return next(error) if error?
+	# 			if user?
+	# 				UserHandler.setupLoginData user, ->
+	# 				LoginRateLimiter.recordSuccessfulLogin email
+	# 				AuthenticationController._recordSuccessfulLogin user._id
+	# 				AuthenticationController.establishUserSession req, user, (error) ->
+	# 					return next(error) if error?
+	# 					req.session.justLoggedIn = true
+	# 					logger.log email: email, user_id: user._id.toString(), "successful log in"
+	# 					Analytics.recordEvent user._id, "user-logged-in"
+	# 					res.json redir: redir
+	# 			else
+	# 				AuthenticationController._recordFailedLogin()
+	# 				logger.log email: email, "failed log in"
+	# 				res.json message:
+	# 					text: req.i18n.translate("email_or_password_wrong_try_again"),
+	# 					type: 'error'

+ 12 - 15
services/web/app/coffee/Features/Authorization/AuthorizationMiddlewear.coffee

@@ -3,6 +3,7 @@ async = require "async"
 logger = require "logger-sharelatex"
 logger = require "logger-sharelatex"
 ObjectId = require("mongojs").ObjectId
 ObjectId = require("mongojs").ObjectId
 Errors = require "../Errors/Errors"
 Errors = require "../Errors/Errors"
+AuthenticationController = require "../Authentication/AuthenticationController"
 
 
 module.exports = AuthorizationMiddlewear =
 module.exports = AuthorizationMiddlewear =
 	ensureUserCanReadMultipleProjects: (req, res, next) ->
 	ensureUserCanReadMultipleProjects: (req, res, next) ->
@@ -20,7 +21,7 @@ module.exports = AuthorizationMiddlewear =
 					AuthorizationMiddlewear.redirectToRestricted req, res, next
 					AuthorizationMiddlewear.redirectToRestricted req, res, next
 				else
 				else
 					next()
 					next()
-		
+
 	ensureUserCanReadProject: (req, res, next) ->
 	ensureUserCanReadProject: (req, res, next) ->
 		AuthorizationMiddlewear._getUserAndProjectId req, (error, user_id, project_id) ->
 		AuthorizationMiddlewear._getUserAndProjectId req, (error, user_id, project_id) ->
 			return next(error) if error?
 			return next(error) if error?
@@ -32,7 +33,7 @@ module.exports = AuthorizationMiddlewear =
 				else
 				else
 					logger.log {user_id, project_id}, "denying user read access to project"
 					logger.log {user_id, project_id}, "denying user read access to project"
 					AuthorizationMiddlewear.redirectToRestricted req, res, next
 					AuthorizationMiddlewear.redirectToRestricted req, res, next
-		
+
 	ensureUserCanWriteProjectSettings: (req, res, next) ->
 	ensureUserCanWriteProjectSettings: (req, res, next) ->
 		AuthorizationMiddlewear._getUserAndProjectId req, (error, user_id, project_id) ->
 		AuthorizationMiddlewear._getUserAndProjectId req, (error, user_id, project_id) ->
 			return next(error) if error?
 			return next(error) if error?
@@ -44,7 +45,7 @@ module.exports = AuthorizationMiddlewear =
 				else
 				else
 					logger.log {user_id, project_id}, "denying user write access to project settings"
 					logger.log {user_id, project_id}, "denying user write access to project settings"
 					AuthorizationMiddlewear.redirectToRestricted req, res, next
 					AuthorizationMiddlewear.redirectToRestricted req, res, next
-		
+
 	ensureUserCanWriteProjectContent: (req, res, next) ->
 	ensureUserCanWriteProjectContent: (req, res, next) ->
 		AuthorizationMiddlewear._getUserAndProjectId req, (error, user_id, project_id) ->
 		AuthorizationMiddlewear._getUserAndProjectId req, (error, user_id, project_id) ->
 			return next(error) if error?
 			return next(error) if error?
@@ -56,7 +57,7 @@ module.exports = AuthorizationMiddlewear =
 				else
 				else
 					logger.log {user_id, project_id}, "denying user write access to project settings"
 					logger.log {user_id, project_id}, "denying user write access to project settings"
 					AuthorizationMiddlewear.redirectToRestricted req, res, next
 					AuthorizationMiddlewear.redirectToRestricted req, res, next
-		
+
 	ensureUserCanAdminProject: (req, res, next) ->
 	ensureUserCanAdminProject: (req, res, next) ->
 		AuthorizationMiddlewear._getUserAndProjectId req, (error, user_id, project_id) ->
 		AuthorizationMiddlewear._getUserAndProjectId req, (error, user_id, project_id) ->
 			return next(error) if error?
 			return next(error) if error?
@@ -68,7 +69,7 @@ module.exports = AuthorizationMiddlewear =
 				else
 				else
 					logger.log {user_id, project_id}, "denying user admin access to project"
 					logger.log {user_id, project_id}, "denying user admin access to project"
 					AuthorizationMiddlewear.redirectToRestricted req, res, next
 					AuthorizationMiddlewear.redirectToRestricted req, res, next
-		
+
 	ensureUserIsSiteAdmin: (req, res, next) ->
 	ensureUserIsSiteAdmin: (req, res, next) ->
 		AuthorizationMiddlewear._getUserId req, (error, user_id) ->
 		AuthorizationMiddlewear._getUserId req, (error, user_id) ->
 			return next(error) if error?
 			return next(error) if error?
@@ -90,22 +91,18 @@ module.exports = AuthorizationMiddlewear =
 		AuthorizationMiddlewear._getUserId req, (error, user_id) ->
 		AuthorizationMiddlewear._getUserId req, (error, user_id) ->
 			return callback(error) if error?
 			return callback(error) if error?
 			callback(null, user_id, project_id)
 			callback(null, user_id, project_id)
-	
+
 	_getUserId: (req, callback = (error, user_id) ->) ->
 	_getUserId: (req, callback = (error, user_id) ->) ->
-		if req.session?.user?._id?
-			user_id = req.session.user._id
-		else
-			user_id = null
-		callback null, user_id
-		
+		user_id = AuthenticationController.getLoggedInUserId(req)
+		return callback(null, user_id)
+
 	redirectToRestricted: (req, res, next) ->
 	redirectToRestricted: (req, res, next) ->
 		res.redirect "/restricted"
 		res.redirect "/restricted"
-	
+
 	restricted : (req, res, next)->
 	restricted : (req, res, next)->
-		if req.session.user?
+		if AuthenticationController.isUserLoggedIn()?
 			res.render 'user/restricted',
 			res.render 'user/restricted',
 				title:'restricted'
 				title:'restricted'
 		else
 		else
 			logger.log "user not logged in and trying to access #{req.url}, being redirected to login"
 			logger.log "user not logged in and trying to access #{req.url}, being redirected to login"
 			res.redirect '/register'
 			res.redirect '/register'
-		

+ 6 - 2
services/web/app/coffee/Features/Chat/ChatController.coffee

@@ -1,14 +1,18 @@
 ChatHandler = require("./ChatHandler")
 ChatHandler = require("./ChatHandler")
 EditorRealTimeController = require("../Editor/EditorRealTimeController")
 EditorRealTimeController = require("../Editor/EditorRealTimeController")
 logger = require("logger-sharelatex")
 logger = require("logger-sharelatex")
+AuthenticationController = require('../Authentication/AuthenticationController')
 
 
 module.exports =
 module.exports =
 
 
 
 
-	sendMessage: (req, res)->
+	sendMessage: (req, res, next)->
 		project_id = req.params.Project_id
 		project_id = req.params.Project_id
-		user_id = req.session.user._id
 		messageContent = req.body.content
 		messageContent = req.body.content
+		user_id = AuthenticationController.getLoggedInUserId(req)
+		if !user_id?
+			err = new Error('no logged-in user')
+			return next(err)
 		ChatHandler.sendMessage project_id, user_id, messageContent, (err, builtMessge)->
 		ChatHandler.sendMessage project_id, user_id, messageContent, (err, builtMessge)->
 			if err?
 			if err?
 				logger.err err:err, project_id:project_id, user_id:user_id, messageContent:messageContent, "problem sending message to chat api"
 				logger.err err:err, project_id:project_id, user_id:user_id, messageContent:messageContent, "problem sending message to chat api"

+ 66 - 61
services/web/app/coffee/Features/Collaborators/CollaboratorsInviteController.coffee

@@ -8,6 +8,7 @@ EmailHelper = require "../Helpers/EmailHelper"
 EditorRealTimeController = require("../Editor/EditorRealTimeController")
 EditorRealTimeController = require("../Editor/EditorRealTimeController")
 NotificationsBuilder = require("../Notifications/NotificationsBuilder")
 NotificationsBuilder = require("../Notifications/NotificationsBuilder")
 AnalyticsManger = require("../Analytics/AnalyticsManager")
 AnalyticsManger = require("../Analytics/AnalyticsManager")
+AuthenticationController = require("../Authentication/AuthenticationController")
 
 
 module.exports = CollaboratorsInviteController =
 module.exports = CollaboratorsInviteController =
 
 
@@ -23,26 +24,27 @@ module.exports = CollaboratorsInviteController =
 	inviteToProject: (req, res, next) ->
 	inviteToProject: (req, res, next) ->
 		projectId = req.params.Project_id
 		projectId = req.params.Project_id
 		email = req.body.email
 		email = req.body.email
-		sendingUser = req.session.user
-		sendingUserId = sendingUser._id
-		logger.log {projectId, email, sendingUserId}, "inviting to project"
-		LimitationsManager.canAddXCollaborators projectId, 1, (error, allowed) =>
-			return next(error) if error?
-			if !allowed
-				logger.log {projectId, email, sendingUserId}, "not allowed to invite more users to project"
-				return res.json {invite: null}
-			{email, privileges} = req.body
-			email = EmailHelper.parseEmail(email)
-			if !email? or email == ""
-				logger.log {projectId, email, sendingUserId}, "invalid email address"
-				return res.sendStatus(400)
-			CollaboratorsInviteHandler.inviteToProject projectId, sendingUser, email, privileges, (err, invite) ->
-				if err?
-					logger.err {projectId, email, sendingUserId}, "error creating project invite"
-					return next(err)
-				logger.log {projectId, email, sendingUserId}, "invite created"
-				EditorRealTimeController.emitToRoom(projectId, 'project:membership:changed', {invites: true})
-				return res.json {invite: invite}
+		AuthenticationController.getLoggedInUser req, (err, sendingUser) ->
+			return callback(err) if err?
+			sendingUserId = sendingUser._id
+			logger.log {projectId, email, sendingUserId}, "inviting to project"
+			LimitationsManager.canAddXCollaborators projectId, 1, (error, allowed) =>
+				return next(error) if error?
+				if !allowed
+					logger.log {projectId, email, sendingUserId}, "not allowed to invite more users to project"
+					return res.json {invite: null}
+				{email, privileges} = req.body
+				email = EmailHelper.parseEmail(email)
+				if !email? or email == ""
+					logger.log {projectId, email, sendingUserId}, "invalid email address"
+					return res.sendStatus(400)
+				CollaboratorsInviteHandler.inviteToProject projectId, sendingUser, email, privileges, (err, invite) ->
+					if err?
+						logger.err {projectId, email, sendingUserId}, "error creating project invite"
+						return next(err)
+					logger.log {projectId, email, sendingUserId}, "invite created"
+					EditorRealTimeController.emitToRoom(projectId, 'project:membership:changed', {invites: true})
+					return res.json {invite: invite}
 
 
 	revokeInvite: (req, res, next) ->
 	revokeInvite: (req, res, next) ->
 		projectId = req.params.Project_id
 		projectId = req.params.Project_id
@@ -58,67 +60,70 @@ module.exports = CollaboratorsInviteController =
 	resendInvite: (req, res, next) ->
 	resendInvite: (req, res, next) ->
 		projectId = req.params.Project_id
 		projectId = req.params.Project_id
 		inviteId = req.params.invite_id
 		inviteId = req.params.invite_id
-		sendingUser = req.session.user
 		logger.log {projectId, inviteId}, "resending invite"
 		logger.log {projectId, inviteId}, "resending invite"
-		CollaboratorsInviteHandler.resendInvite projectId, sendingUser, inviteId, (err) ->
-			if err?
-				logger.err {projectId, inviteId}, "error resending invite"
-				return next(err)
-			res.sendStatus(201)
+		AuthenticationController.getLoggedInUser req, (err, sendingUser) ->
+			return callback(err) if err?
+			CollaboratorsInviteHandler.resendInvite projectId, sendingUser, inviteId, (err) ->
+				if err?
+					logger.err {projectId, inviteId}, "error resending invite"
+					return next(err)
+				res.sendStatus(201)
 
 
 	viewInvite: (req, res, next) ->
 	viewInvite: (req, res, next) ->
 		projectId = req.params.Project_id
 		projectId = req.params.Project_id
 		token = req.params.token
 		token = req.params.token
-		currentUser = req.session.user
 		_renderInvalidPage = () ->
 		_renderInvalidPage = () ->
 			logger.log {projectId, token}, "invite not valid, rendering not-valid page"
 			logger.log {projectId, token}, "invite not valid, rendering not-valid page"
 			res.render "project/invite/not-valid", {title: "Invalid Invite"}
 			res.render "project/invite/not-valid", {title: "Invalid Invite"}
 		# check if the user is already a member of the project
 		# check if the user is already a member of the project
-		CollaboratorsHandler.isUserMemberOfProject currentUser._id, projectId, (err, isMember, _privilegeLevel) ->
-			if err?
-				logger.err {err, projectId}, "error checking if user is member of project"
-				return next(err)
-			if isMember
-				logger.log {projectId, userId: currentUser._id}, "user is already a member of this project, redirecting"
-				return res.redirect "/project/#{projectId}"
-			# get the invite
-			CollaboratorsInviteHandler.getInviteByToken projectId, token, (err, invite) ->
+		AuthenticationController.getLoggedInUser req, (err, currentUser) ->
+			return callback(err) if err?
+			CollaboratorsHandler.isUserMemberOfProject currentUser._id, projectId, (err, isMember, _privilegeLevel) ->
 				if err?
 				if err?
-					logger.err {projectId, token}, "error getting invite by token"
+					logger.err {err, projectId}, "error checking if user is member of project"
 					return next(err)
 					return next(err)
-				# check if invite is gone, or otherwise non-existent
-				if !invite?
-					logger.log {projectId, token}, "no invite found for this token"
-					return _renderInvalidPage()
-				# check the user who sent the invite exists
-				UserGetter.getUser {_id: invite.sendingUserId}, {email: 1, first_name: 1, last_name: 1}, (err, owner) ->
+				if isMember
+					logger.log {projectId, userId: currentUser._id}, "user is already a member of this project, redirecting"
+					return res.redirect "/project/#{projectId}"
+				# get the invite
+				CollaboratorsInviteHandler.getInviteByToken projectId, token, (err, invite) ->
 					if err?
 					if err?
-						logger.err {err, projectId}, "error getting project owner"
+						logger.err {projectId, token}, "error getting invite by token"
 						return next(err)
 						return next(err)
-					if !owner?
-						logger.log {projectId}, "no project owner found"
+					# check if invite is gone, or otherwise non-existent
+					if !invite?
+						logger.log {projectId, token}, "no invite found for this token"
 						return _renderInvalidPage()
 						return _renderInvalidPage()
-					# fetch the project name
-					ProjectGetter.getProject projectId, {}, (err, project) ->
+					# check the user who sent the invite exists
+					UserGetter.getUser {_id: invite.sendingUserId}, {email: 1, first_name: 1, last_name: 1}, (err, owner) ->
 						if err?
 						if err?
-							logger.err {err, projectId}, "error getting project"
+							logger.err {err, projectId}, "error getting project owner"
 							return next(err)
 							return next(err)
-						if !project?
-							logger.log {projectId}, "no project found"
+						if !owner?
+							logger.log {projectId}, "no project owner found"
 							return _renderInvalidPage()
 							return _renderInvalidPage()
-						# finally render the invite
-						res.render "project/invite/show", {invite, project, owner, title: "Project Invite"}
+						# fetch the project name
+						ProjectGetter.getProject projectId, {}, (err, project) ->
+							if err?
+								logger.err {err, projectId}, "error getting project"
+								return next(err)
+							if !project?
+								logger.log {projectId}, "no project found"
+								return _renderInvalidPage()
+							# finally render the invite
+							res.render "project/invite/show", {invite, project, owner, title: "Project Invite"}
 
 
 	acceptInvite: (req, res, next) ->
 	acceptInvite: (req, res, next) ->
 		projectId = req.params.Project_id
 		projectId = req.params.Project_id
 		inviteId = req.params.invite_id
 		inviteId = req.params.invite_id
 		{token} = req.body
 		{token} = req.body
-		currentUser = req.session.user
 		logger.log {projectId, inviteId, userId: currentUser._id}, "accepting invite"
 		logger.log {projectId, inviteId, userId: currentUser._id}, "accepting invite"
-		CollaboratorsInviteHandler.acceptInvite projectId, inviteId, token, currentUser, (err) ->
-			if err?
-				logger.err {projectId, inviteId}, "error accepting invite by token"
-				return next(err)
-			EditorRealTimeController.emitToRoom projectId, 'project:membership:changed', {invites: true, members: true}
-			AnalyticsManger.recordEvent(currentUser._id, "project-invite-accept", {inviteId:inviteId, projectId:projectId})
-			res.redirect "/project/#{projectId}"
+		AuthenticationController.getLoggedInUser req, (err, currentUser) ->
+			return callback(err) if err?
+			CollaboratorsInviteHandler.acceptInvite projectId, inviteId, token, currentUser, (err) ->
+				if err?
+					logger.err {projectId, inviteId}, "error accepting invite by token"
+					return next(err)
+				EditorRealTimeController.emitToRoom projectId, 'project:membership:changed', {invites: true, members: true}
+				AnalyticsManger.recordEvent(currentUser._id, "project-invite-accept", {inviteId:inviteId, projectId:projectId})
+				res.redirect "/project/#{projectId}"

+ 31 - 31
services/web/app/coffee/Features/Compile/CompileController.coffee

@@ -16,53 +16,53 @@ module.exports = CompileController =
 		res.setTimeout(5 * 60 * 1000)
 		res.setTimeout(5 * 60 * 1000)
 		project_id = req.params.Project_id
 		project_id = req.params.Project_id
 		isAutoCompile = !!req.query?.auto_compile
 		isAutoCompile = !!req.query?.auto_compile
-		AuthenticationController.getLoggedInUserId req, (error, user_id) ->
+		user_id = AuthenticationController.getLoggedInUserId req
+		options = {
+			isAutoCompile: isAutoCompile
+		}
+		if req.body?.rootDoc_id?
+			options.rootDoc_id = req.body.rootDoc_id
+		else if req.body?.settingsOverride?.rootDoc_id? # Can be removed after deploy
+			options.rootDoc_id = req.body.settingsOverride.rootDoc_id
+		if req.body?.compiler
+			options.compiler = req.body.compiler
+		if req.body?.draft
+			options.draft = req.body.draft
+		if req.body?.check in ['validate', 'error', 'silent']
+			options.check = req.body.check
+		logger.log {options:options, project_id:project_id, user_id:user_id}, "got compile request"
+		CompileManager.compile project_id, user_id, options, (error, status, outputFiles, clsiServerId, limits, validationProblems) ->
 			return next(error) if error?
 			return next(error) if error?
-			options = {
-				isAutoCompile: isAutoCompile
+			res.contentType("application/json")
+			res.status(200).send JSON.stringify {
+				status: status
+				outputFiles: outputFiles
+				compileGroup: limits?.compileGroup
+				clsiServerId:clsiServerId
+				validationProblems:validationProblems
 			}
 			}
-			if req.body?.rootDoc_id?
-				options.rootDoc_id = req.body.rootDoc_id
-			else if req.body?.settingsOverride?.rootDoc_id? # Can be removed after deploy
-				options.rootDoc_id = req.body.settingsOverride.rootDoc_id
-			if req.body?.compiler
-				options.compiler = req.body.compiler
-			if req.body?.draft
-				options.draft = req.body.draft
-			if req.body?.check in ['validate', 'error', 'silent']
-				options.check = req.body.check
-			logger.log {options:options, project_id:project_id, user_id:user_id}, "got compile request"
-			CompileManager.compile project_id, user_id, options, (error, status, outputFiles, clsiServerId, limits, validationProblems) ->
-				return next(error) if error?
-				res.contentType("application/json")
-				res.status(200).send JSON.stringify {
-					status: status
-					outputFiles: outputFiles
-					compileGroup: limits?.compileGroup
-					clsiServerId:clsiServerId
-					validationProblems:validationProblems
-				}
 
 
 	stopCompile: (req, res, next = (error) ->) ->
 	stopCompile: (req, res, next = (error) ->) ->
 		project_id = req.params.Project_id
 		project_id = req.params.Project_id
-		AuthenticationController.getLoggedInUserId req, (error, user_id) ->
+		user_id = AuthenticationController.getLoggedInUserId req
+		logger.log {project_id:project_id, user_id:user_id}, "stop compile request"
+		CompileManager.stopCompile project_id, user_id, (error) ->
 			return next(error) if error?
 			return next(error) if error?
-			logger.log {project_id:project_id, user_id:user_id}, "stop compile request"
-			CompileManager.stopCompile project_id, user_id, (error) ->
-				return next(error) if error?
-				res.status(200).send()
+			res.status(200).send()
 
 
 	_compileAsUser: (req, callback) ->
 	_compileAsUser: (req, callback) ->
 		# callback with user_id if per-user, undefined otherwise
 		# callback with user_id if per-user, undefined otherwise
 		if not Settings.disablePerUserCompiles
 		if not Settings.disablePerUserCompiles
-			AuthenticationController.getLoggedInUserId req, callback # -> (error, user_id)
+			user_id = AuthenticationController.getLoggedInUserId req
+			return callback(null, user_id)
 		else
 		else
 			callback() # do a per-project compile, not per-user
 			callback() # do a per-project compile, not per-user
 
 
 	_downloadAsUser: (req, callback) ->
 	_downloadAsUser: (req, callback) ->
 		# callback with user_id if per-user, undefined otherwise
 		# callback with user_id if per-user, undefined otherwise
 		if not Settings.disablePerUserCompiles
 		if not Settings.disablePerUserCompiles
-			AuthenticationController.getLoggedInUserId req, callback # -> (error, user_id)
+			user_id = AuthenticationController.getLoggedInUserId req
+			return callback(null, user_id)
 		else
 		else
 			callback() # do a per-project compile, not per-user
 			callback() # do a per-project compile, not per-user
 
 

+ 22 - 23
services/web/app/coffee/Features/Contacts/ContactController.coffee

@@ -6,33 +6,32 @@ Modules = require "../../infrastructure/Modules"
 
 
 module.exports = ContactsController =
 module.exports = ContactsController =
 	getContacts: (req, res, next) ->
 	getContacts: (req, res, next) ->
-		AuthenticationController.getLoggedInUserId req, (error, user_id) ->
+		user_id = AuthenticationController.getLoggedInUserId req
+		ContactManager.getContactIds user_id, {limit: 50}, (error, contact_ids) ->
 			return next(error) if error?
 			return next(error) if error?
-			ContactManager.getContactIds user_id, {limit: 50}, (error, contact_ids) ->
+			UserGetter.getUsers contact_ids, {
+				email: 1, first_name: 1, last_name: 1, holdingAccount: 1
+			}, (error, contacts) ->
 				return next(error) if error?
 				return next(error) if error?
-				UserGetter.getUsers contact_ids, {
-					email: 1, first_name: 1, last_name: 1, holdingAccount: 1
-				}, (error, contacts) ->
+
+				# UserGetter.getUsers may not preserve order so put them back in order
+				positions = {}
+				for contact_id, i in contact_ids
+					positions[contact_id] = i
+				contacts.sort (a,b) -> positions[a._id?.toString()] - positions[b._id?.toString()]
+
+				# Don't count holding accounts to discourage users from repeating mistakes (mistyped or wrong emails, etc)
+				contacts = contacts.filter (c) -> !c.holdingAccount
+
+				contacts = contacts.map(ContactsController._formatContact)
+
+				Modules.hooks.fire "getContacts", user_id, contacts, (error, additional_contacts) ->
 					return next(error) if error?
 					return next(error) if error?
-					
-					# UserGetter.getUsers may not preserve order so put them back in order
-					positions = {}
-					for contact_id, i in contact_ids
-						positions[contact_id] = i
-					contacts.sort (a,b) -> positions[a._id?.toString()] - positions[b._id?.toString()]
+					contacts = contacts.concat(additional_contacts...)
+					res.send({
+						contacts: contacts
+					})
 
 
-					# Don't count holding accounts to discourage users from repeating mistakes (mistyped or wrong emails, etc)
-					contacts = contacts.filter (c) -> !c.holdingAccount
-					
-					contacts = contacts.map(ContactsController._formatContact)
-					
-					Modules.hooks.fire "getContacts", user_id, contacts, (error, additional_contacts) ->
-						return next(error) if error?
-						contacts = contacts.concat(additional_contacts...)
-						res.send({
-							contacts: contacts
-						})
-	
 	_formatContact: (contact) ->
 	_formatContact: (contact) ->
 		return  {
 		return  {
 			id: contact._id?.toString()
 			id: contact._id?.toString()

+ 5 - 3
services/web/app/coffee/Features/Notifications/NotificationsController.coffee

@@ -1,18 +1,20 @@
 NotificationsHandler = require("./NotificationsHandler")
 NotificationsHandler = require("./NotificationsHandler")
+AuthenticationController = require("../Authentication/AuthenticationController")
 logger = require("logger-sharelatex")
 logger = require("logger-sharelatex")
 _ = require("underscore")
 _ = require("underscore")
 
 
 module.exports =
 module.exports =
 
 
 	getAllUnreadNotifications: (req, res)->
 	getAllUnreadNotifications: (req, res)->
-		NotificationsHandler.getUserNotifications req.session.user._id, (err, unreadNotifications)->
-			unreadNotifications = _.map unreadNotifications, (notification)-> 
+		user_id = AuthenticationController.getLoggedInUserId(req)
+		NotificationsHandler.getUserNotifications user_id, (err, unreadNotifications)->
+			unreadNotifications = _.map unreadNotifications, (notification)->
 				notification.html = req.i18n.translate(notification.templateKey, notification.messageOpts)
 				notification.html = req.i18n.translate(notification.templateKey, notification.messageOpts)
 				return notification
 				return notification
 			res.send(unreadNotifications)
 			res.send(unreadNotifications)
 
 
 	markNotificationAsRead: (req, res)->
 	markNotificationAsRead: (req, res)->
-		user_id = req.session.user._id
+		user_id = AuthenticationController.getLoggedInUserId(req)
 		notification_id = req.params.notification_id
 		notification_id = req.params.notification_id
 		NotificationsHandler.markAsRead user_id, notification_id, ->
 		NotificationsHandler.markAsRead user_id, notification_id, ->
 			res.send()
 			res.send()

+ 64 - 59
services/web/app/coffee/Features/Project/ProjectController.coffee

@@ -18,6 +18,7 @@ InactiveProjectManager = require("../InactiveData/InactiveProjectManager")
 ProjectUpdateHandler = require("./ProjectUpdateHandler")
 ProjectUpdateHandler = require("./ProjectUpdateHandler")
 ProjectGetter = require("./ProjectGetter")
 ProjectGetter = require("./ProjectGetter")
 PrivilegeLevels = require("../Authorization/PrivilegeLevels")
 PrivilegeLevels = require("../Authorization/PrivilegeLevels")
+AuthenticationController = require("../Authentication/AuthenticationController")
 
 
 module.exports = ProjectController =
 module.exports = ProjectController =
 
 
@@ -88,32 +89,34 @@ module.exports = ProjectController =
 		project_id = req.params.Project_id
 		project_id = req.params.Project_id
 		projectName = req.body.projectName
 		projectName = req.body.projectName
 		logger.log project_id:project_id, projectName:projectName, "cloning project"
 		logger.log project_id:project_id, projectName:projectName, "cloning project"
-		if !req.session.user?
+		if !AuthenticationController.isUserLoggedIn()?
 			return res.send redir:"/register"
 			return res.send redir:"/register"
-		projectDuplicator.duplicate req.session.user, project_id, projectName, (err, project)->
-			if err?
-				logger.error err:err, project_id: project_id, user_id: req.session.user._id, "error cloning project"
-				return next(err)
-			res.send(project_id:project._id)
+		AuthenticationController.getLoggedInUser req, (err, currentUser) ->
+			return next(err) if err?
+			projectDuplicator.duplicate currentUser, project_id, projectName, (err, project)->
+				if err?
+					logger.error err:err, project_id: project_id, user_id: currentUser._id, "error cloning project"
+					return next(err)
+				res.send(project_id:project._id)
 
 
 
 
 	newProject: (req, res)->
 	newProject: (req, res)->
-		user = req.session.user
+		user_id = AuthenticationController.getLoggedInUserId(req)
 		projectName = req.body.projectName?.trim()
 		projectName = req.body.projectName?.trim()
 		template = req.body.template
 		template = req.body.template
-		logger.log user: user, projectType: template, name: projectName, "creating project"
+		logger.log user: user_id, projectType: template, name: projectName, "creating project"
 		async.waterfall [
 		async.waterfall [
 			(cb)->
 			(cb)->
 				if template == 'example'
 				if template == 'example'
-					projectCreationHandler.createExampleProject user._id, projectName, cb
+					projectCreationHandler.createExampleProject user_id, projectName, cb
 				else
 				else
-					projectCreationHandler.createBasicProject user._id, projectName, cb
+					projectCreationHandler.createBasicProject user_id, projectName, cb
 		], (err, project)->
 		], (err, project)->
 			if err?
 			if err?
-				logger.error err: err, project: project, user: user, name: projectName, templateType: template, "error creating project"
+				logger.error err: err, project: project, user: user_id, name: projectName, templateType: template, "error creating project"
 				res.sendStatus 500
 				res.sendStatus 500
 			else
 			else
-				logger.log project: project, user: user, name: projectName, templateType: template, "created project"
+				logger.log project: project, user: user_id, name: projectName, templateType: template, "created project"
 				res.send {project_id:project._id}
 				res.send {project_id:project._id}
 
 
 
 
@@ -131,51 +134,53 @@ module.exports = ProjectController =
 
 
 	projectListPage: (req, res, next)->
 	projectListPage: (req, res, next)->
 		timer = new metrics.Timer("project-list")
 		timer = new metrics.Timer("project-list")
-		user_id = req.session.user._id
-		async.parallel {
-			tags: (cb)->
-				TagsHandler.getAllTags user_id, cb
-			notifications: (cb)->
-				NotificationsHandler.getUserNotifications user_id, cb
-			projects: (cb)->
-				ProjectGetter.findAllUsersProjects user_id, 'name lastUpdated publicAccesLevel archived owner_ref', cb
-			hasSubscription: (cb)->
-				LimitationsManager.userHasSubscriptionOrIsGroupMember req.session.user, cb
-			user: (cb) ->
-				User.findById user_id, "featureSwitches", cb
-			}, (err, results)->
-				if err?
-					logger.err err:err, "error getting data for project list page"
-					return next(err)
-				logger.log results:results, user_id:user_id, "rendering project list"
-				tags = results.tags[0]
-				notifications = require("underscore").map results.notifications, (notification)->
-					notification.html = req.i18n.translate(notification.templateKey, notification.messageOpts)
-					return notification
-				projects = ProjectController._buildProjectList results.projects[0], results.projects[1], results.projects[2]
-				user = results.user
-				ProjectController._injectProjectOwners projects, (error, projects) ->
-					return next(error) if error?
-
-					viewModel = {
-						title:'your_projects'
-						priority_title: true
-						projects: projects
-						tags: tags
-						notifications: notifications or []
-						user: user
-						hasSubscription: results.hasSubscription[0]
-					}
-
-					if Settings?.algolia?.app_id? and Settings?.algolia?.read_only_api_key?
-						viewModel.showUserDetailsArea = true
-						viewModel.algolia_api_key = Settings.algolia.read_only_api_key
-						viewModel.algolia_app_id = Settings.algolia.app_id
-					else
-						viewModel.showUserDetailsArea = false
-
-					res.render 'project/list', viewModel
-					timer.done()
+		user_id = AuthenticationController.getLoggedInUserId(req)
+		AuthenticationController.getLoggedInUser req, (err, currentUser) ->
+			return next(err) if err?
+			async.parallel {
+				tags: (cb)->
+					TagsHandler.getAllTags user_id, cb
+				notifications: (cb)->
+					NotificationsHandler.getUserNotifications user_id, cb
+				projects: (cb)->
+					ProjectGetter.findAllUsersProjects user_id, 'name lastUpdated publicAccesLevel archived owner_ref', cb
+				hasSubscription: (cb)->
+					LimitationsManager.userHasSubscriptionOrIsGroupMember currentUser, cb
+				user: (cb) ->
+					User.findById user_id, "featureSwitches", cb
+				}, (err, results)->
+					if err?
+						logger.err err:err, "error getting data for project list page"
+						return next(err)
+					logger.log results:results, user_id:user_id, "rendering project list"
+					tags = results.tags[0]
+					notifications = require("underscore").map results.notifications, (notification)->
+						notification.html = req.i18n.translate(notification.templateKey, notification.messageOpts)
+						return notification
+					projects = ProjectController._buildProjectList results.projects[0], results.projects[1], results.projects[2]
+					user = results.user
+					ProjectController._injectProjectOwners projects, (error, projects) ->
+						return next(error) if error?
+
+						viewModel = {
+							title:'your_projects'
+							priority_title: true
+							projects: projects
+							tags: tags
+							notifications: notifications or []
+							user: user
+							hasSubscription: results.hasSubscription[0]
+						}
+
+						if Settings?.algolia?.app_id? and Settings?.algolia?.read_only_api_key?
+							viewModel.showUserDetailsArea = true
+							viewModel.algolia_api_key = Settings.algolia.read_only_api_key
+							viewModel.algolia_app_id = Settings.algolia.app_id
+						else
+							viewModel.showUserDetailsArea = false
+
+						res.render 'project/list', viewModel
+						timer.done()
 
 
 
 
 	loadEditor: (req, res, next)->
 	loadEditor: (req, res, next)->
@@ -183,8 +188,8 @@ module.exports = ProjectController =
 		if !Settings.editorIsOpen
 		if !Settings.editorIsOpen
 			return res.render("general/closed", {title:"updating_site"})
 			return res.render("general/closed", {title:"updating_site"})
 
 
-		if req.session.user?
-			user_id = req.session.user._id
+		if AuthenticationController.isUserLoggedIn(req)?
+			user_id = AuthenticationController.getLoggedInUserId(req)
 			anonymous = false
 			anonymous = false
 		else
 		else
 			anonymous = true
 			anonymous = true

+ 4 - 2
services/web/app/coffee/Features/Referal/ReferalController.coffee

@@ -1,9 +1,11 @@
 logger = require('logger-sharelatex')
 logger = require('logger-sharelatex')
 ReferalHandler = require('./ReferalHandler')
 ReferalHandler = require('./ReferalHandler')
+AuthenticationController = require('../Authentication/AuthenticationController')
 
 
-module.exports = 
+module.exports =
 	bonus: (req, res)->
 	bonus: (req, res)->
-		ReferalHandler.getReferedUserIds req.session.user._id, (err, refered_users)->
+		user_id = AuthenticationController.getLoggedInUserId(req)
+		ReferalHandler.getReferedUserIds user_id, (err, refered_users)->
 			res.render "referal/bonus",
 			res.render "referal/bonus",
 				title: "bonus_please_recommend_us"
 				title: "bonus_please_recommend_us"
 				refered_users: refered_users
 				refered_users: refered_users

+ 4 - 3
services/web/app/coffee/Features/Referal/ReferalMiddleware.coffee

@@ -1,11 +1,12 @@
 User = require("../../models/User").User
 User = require("../../models/User").User
+AuthenticationController = require('../Authentication/AuthenticationController')
 
 
 module.exports = RefererMiddleware =
 module.exports = RefererMiddleware =
 	getUserReferalId: (req, res, next) ->
 	getUserReferalId: (req, res, next) ->
-		if req.session? and req.session.user?
-			User.findById req.session.user._id, (error, user) ->
+		if AuthenticationController.isUserLoggedIn()?
+			AuthenticationController.getLoggedInUser req, (error, user) ->
 				return next(error) if error?
 				return next(error) if error?
-				req.session.user.referal_id = user.referal_id
+				req.user.referal_id = user.referal_id
 				next()
 				next()
 		else
 		else
 			next()
 			next()

+ 6 - 8
services/web/app/coffee/Features/Security/RateLimiterMiddlewear.coffee

@@ -1,24 +1,22 @@
 RateLimiter = require "../../infrastructure/RateLimiter"
 RateLimiter = require "../../infrastructure/RateLimiter"
 logger = require "logger-sharelatex"
 logger = require "logger-sharelatex"
+AuthenticationController = require('../Authentication/AuthenticationController')
 
 
 module.exports = RateLimiterMiddlewear =
 module.exports = RateLimiterMiddlewear =
 	###
 	###
 	Do not allow more than opts.maxRequests from a single client in
 	Do not allow more than opts.maxRequests from a single client in
 	opts.timeInterval. Pass an array of opts.params to segment this based on
 	opts.timeInterval. Pass an array of opts.params to segment this based on
 	parameters in the request URL, e.g.:
 	parameters in the request URL, e.g.:
-	
+
 	    app.get "/project/:project_id", RateLimiterMiddlewear.rateLimit(endpointName: "open-editor", params: ["project_id"])
 	    app.get "/project/:project_id", RateLimiterMiddlewear.rateLimit(endpointName: "open-editor", params: ["project_id"])
-	
+
 	will rate limit each project_id separately.
 	will rate limit each project_id separately.
-	
+
 	Unique clients are identified by user_id if logged in, and IP address if not.
 	Unique clients are identified by user_id if logged in, and IP address if not.
 	###
 	###
 	rateLimit: (opts) ->
 	rateLimit: (opts) ->
 		return (req, res, next) ->
 		return (req, res, next) ->
-			if req.session?.user?
-				user_id = req.session.user._id
-			else
-				user_id = req.ip
+			user_id = AuthenticationController.getLoggedInUserId(req) || req.ip
 			params = (opts.params or []).map (p) -> req.params[p]
 			params = (opts.params or []).map (p) -> req.params[p]
 			params.push user_id
 			params.push user_id
 			if !opts.endpointName?
 			if !opts.endpointName?
@@ -37,4 +35,4 @@ module.exports = RateLimiterMiddlewear =
 					logger.warn options, "rate limit exceeded"
 					logger.warn options, "rate limit exceeded"
 					res.status(429) # Too many requests
 					res.status(429) # Too many requests
 					res.write("Rate limit reached, please try again later")
 					res.write("Rate limit reached, please try again later")
-					res.end()
+					res.end()

+ 3 - 1
services/web/app/coffee/Features/Spelling/SpellingController.coffee

@@ -1,13 +1,15 @@
 request = require 'request'
 request = require 'request'
 Settings = require 'settings-sharelatex'
 Settings = require 'settings-sharelatex'
 logger = require 'logger-sharelatex'
 logger = require 'logger-sharelatex'
+AuthenticationController = require('../Authentication/AuthenticationController')
 
 
 TEN_SECONDS = 1000 * 10
 TEN_SECONDS = 1000 * 10
 
 
 module.exports = SpellingController =
 module.exports = SpellingController =
 	proxyRequestToSpellingApi: (req, res, next) ->
 	proxyRequestToSpellingApi: (req, res, next) ->
+		user_id = AuthenticationController.getLoggedInUserId(req)
 		url = req.url.slice("/spelling".length)
 		url = req.url.slice("/spelling".length)
-		url = "/user/#{req.session.user._id}#{url}"
+		url = "/user/#{user_id}#{url}"
 		req.headers["Host"] = Settings.apis.spelling.host
 		req.headers["Host"] = Settings.apis.spelling.host
 		request(url: Settings.apis.spelling.url + url, method: req.method, headers: req.headers, json: req.body, timeout:TEN_SECONDS)
 		request(url: Settings.apis.spelling.url + url, method: req.method, headers: req.headers, json: req.body, timeout:TEN_SECONDS)
 		.on "error", (error) ->
 		.on "error", (error) ->

+ 3 - 2
services/web/app/coffee/Features/StaticPages/HomeController.coffee

@@ -5,12 +5,13 @@ Path = require "path"
 fs = require "fs"
 fs = require "fs"
 
 
 ErrorController = require "../Errors/ErrorController"
 ErrorController = require "../Errors/ErrorController"
+AuthenticationController = require('../Authentication/AuthenticationController')
 
 
 homepageExists = fs.existsSync Path.resolve(__dirname + "/../../../views/external/home.jade")
 homepageExists = fs.existsSync Path.resolve(__dirname + "/../../../views/external/home.jade")
 
 
 module.exports = HomeController =
 module.exports = HomeController =
 	index : (req,res)->
 	index : (req,res)->
-		if req.session.user
+		if AuthenticationController.isUserLoggedIn(req)?
 			if req.query.scribtex_path?
 			if req.query.scribtex_path?
 				res.redirect "/project?scribtex_path=#{req.query.scribtex_path}"
 				res.redirect "/project?scribtex_path=#{req.query.scribtex_path}"
 			else
 			else
@@ -33,4 +34,4 @@ module.exports = HomeController =
 					res.render "external/#{page}.jade",
 					res.render "external/#{page}.jade",
 						title: title
 						title: title
 				else
 				else
-					ErrorController.notFound(req, res, next)
+					ErrorController.notFound(req, res, next)

+ 2 - 2
services/web/app/coffee/Features/Subscription/SubscriptionController.coffee

@@ -13,7 +13,7 @@ module.exports = SubscriptionController =
 
 
 	plansPage: (req, res, next) ->
 	plansPage: (req, res, next) ->
 		plans = SubscriptionViewModelBuilder.buildViewModel()
 		plans = SubscriptionViewModelBuilder.buildViewModel()
-		if !req.session.user?
+		if AuthenticationController.isUserLoggedIn(req)?
 			baseUrl = "/register?redir="
 			baseUrl = "/register?redir="
 		else
 		else
 			baseUrl = ""
 			baseUrl = ""
@@ -134,7 +134,7 @@ module.exports = SubscriptionController =
 							successURL : "#{Settings.siteUrl}/user/subscription/billing-details/update"
 							successURL : "#{Settings.siteUrl}/user/subscription/billing-details/update"
 							user       :
 							user       :
 								id : user._id
 								id : user._id
-	
+
 	updateBillingDetails: (req, res, next) ->
 	updateBillingDetails: (req, res, next) ->
 		res.redirect "/user/subscription?saved_billing_details=true"
 		res.redirect "/user/subscription?saved_billing_details=true"
 
 

+ 22 - 18
services/web/app/coffee/Features/Subscription/SubscriptionGroupController.coffee

@@ -3,27 +3,28 @@ logger = require("logger-sharelatex")
 SubscriptionLocator = require("./SubscriptionLocator")
 SubscriptionLocator = require("./SubscriptionLocator")
 ErrorsController = require("../Errors/ErrorController")
 ErrorsController = require("../Errors/ErrorController")
 SubscriptionDomainHandler = require("./SubscriptionDomainHandler")
 SubscriptionDomainHandler = require("./SubscriptionDomainHandler")
+AuthenticationController = require('../Authentication/AuthenticationController')
 _ = require("underscore")
 _ = require("underscore")
 async = require("async")
 async = require("async")
 
 
 module.exports =
 module.exports =
 
 
 	addUserToGroup: (req, res)->
 	addUserToGroup: (req, res)->
-		adminUserId = req.session.user._id
+		adminUserId = AuthenticationController.getLoggedInUserId(req)
 		newEmail = req.body?.email?.toLowerCase()?.trim()
 		newEmail = req.body?.email?.toLowerCase()?.trim()
 		logger.log adminUserId:adminUserId, newEmail:newEmail, "adding user to group subscription"
 		logger.log adminUserId:adminUserId, newEmail:newEmail, "adding user to group subscription"
 		SubscriptionGroupHandler.addUserToGroup adminUserId, newEmail, (err, user)->
 		SubscriptionGroupHandler.addUserToGroup adminUserId, newEmail, (err, user)->
 			if err?
 			if err?
 				logger.err err:err, newEmail:newEmail, adminUserId:adminUserId, "error adding user from group"
 				logger.err err:err, newEmail:newEmail, adminUserId:adminUserId, "error adding user from group"
 				return res.sendStatus 500
 				return res.sendStatus 500
-			result = 
+			result =
 				user:user
 				user:user
 			if err and err.limitReached
 			if err and err.limitReached
 				result.limitReached = true
 				result.limitReached = true
 			res.json(result)
 			res.json(result)
 
 
 	removeUserFromGroup: (req, res)->
 	removeUserFromGroup: (req, res)->
-		adminUserId = req.session.user._id
+		adminUserId = AuthenticationController.getLoggedInUserId(req)
 		userToRemove_id = req.params.user_id
 		userToRemove_id = req.params.user_id
 		logger.log adminUserId:adminUserId, userToRemove_id:userToRemove_id, "removing user from group subscription"
 		logger.log adminUserId:adminUserId, userToRemove_id:userToRemove_id, "removing user from group subscription"
 		SubscriptionGroupHandler.removeUserFromGroup adminUserId, userToRemove_id, (err)->
 		SubscriptionGroupHandler.removeUserFromGroup adminUserId, userToRemove_id, (err)->
@@ -31,10 +32,10 @@ module.exports =
 				logger.err err:err, adminUserId:adminUserId, userToRemove_id:userToRemove_id, "error removing user from group"
 				logger.err err:err, adminUserId:adminUserId, userToRemove_id:userToRemove_id, "error removing user from group"
 				return res.sendStatus 500
 				return res.sendStatus 500
 			res.send()
 			res.send()
-			
+
 	removeSelfFromGroup: (req, res)->
 	removeSelfFromGroup: (req, res)->
 		adminUserId = req.query.admin_user_id
 		adminUserId = req.query.admin_user_id
-		userToRemove_id = req.session.user._id
+		userToRemove_id = AuthenticationController.getLoggedInUserId(req)
 		logger.log adminUserId:adminUserId, userToRemove_id:userToRemove_id, "removing user from group subscription after self request"
 		logger.log adminUserId:adminUserId, userToRemove_id:userToRemove_id, "removing user from group subscription after self request"
 		SubscriptionGroupHandler.removeUserFromGroup adminUserId, userToRemove_id, (err)->
 		SubscriptionGroupHandler.removeUserFromGroup adminUserId, userToRemove_id, (err)->
 			if err?
 			if err?
@@ -43,7 +44,7 @@ module.exports =
 			res.send()
 			res.send()
 
 
 	renderSubscriptionGroupAdminPage: (req, res)->
 	renderSubscriptionGroupAdminPage: (req, res)->
-		user_id = req.session.user._id
+		user_id = AuthenticationController.getLoggedInUserId(req)
 		SubscriptionLocator.getUsersSubscription user_id, (err, subscription)->
 		SubscriptionLocator.getUsersSubscription user_id, (err, subscription)->
 			if !subscription.groupPlan
 			if !subscription.groupPlan
 				return res.redirect("/")
 				return res.redirect("/")
@@ -55,11 +56,11 @@ module.exports =
 
 
 	renderGroupInvitePage: (req, res)->
 	renderGroupInvitePage: (req, res)->
 		group_subscription_id = req.params.subscription_id
 		group_subscription_id = req.params.subscription_id
-		user_id = req.session.user._id
+		user_id = AuthenticationController.getLoggedInUserId(req)
 		licence = SubscriptionDomainHandler.findDomainLicenceBySubscriptionId(group_subscription_id)
 		licence = SubscriptionDomainHandler.findDomainLicenceBySubscriptionId(group_subscription_id)
 		if !licence?
 		if !licence?
 			return ErrorsController.notFound(req, res)
 			return ErrorsController.notFound(req, res)
-		jobs = 
+		jobs =
 			partOfGroup: (cb)->
 			partOfGroup: (cb)->
 				SubscriptionGroupHandler.isUserPartOfGroup user_id, licence.group_subscription_id, cb
 				SubscriptionGroupHandler.isUserPartOfGroup user_id, licence.group_subscription_id, cb
 			subscription: (cb)->
 			subscription: (cb)->
@@ -77,15 +78,18 @@ module.exports =
 
 
 	beginJoinGroup: (req, res)->
 	beginJoinGroup: (req, res)->
 		subscription_id = req.params.subscription_id
 		subscription_id = req.params.subscription_id
-		user_id = req.session.user._id
-		licence = SubscriptionDomainHandler.findDomainLicenceBySubscriptionId(subscription_id)
-		if !licence?
-			return ErrorsController.notFound(req, res)
-		SubscriptionGroupHandler.sendVerificationEmail subscription_id, licence.name, req.session.user.email, (err)->
+		AuthenticationController.getLoggedInUser req, (err, currentUser) ->
 			if err?
 			if err?
-				res.sendStatus 500
-			else
-				res.sendStatus 200
+				logger.err {subscription_id}, "error getting current user"
+				return res.sendStatus 500
+			licence = SubscriptionDomainHandler.findDomainLicenceBySubscriptionId(subscription_id)
+			if !licence?
+				return ErrorsController.notFound(req, res)
+			SubscriptionGroupHandler.sendVerificationEmail subscription_id, licence.name, currentUser.email, (err)->
+				if err?
+					res.sendStatus 500
+				else
+					res.sendStatus 200
 
 
 	completeJoin: (req, res)->
 	completeJoin: (req, res)->
 		subscription_id = req.params.subscription_id
 		subscription_id = req.params.subscription_id
@@ -109,10 +113,10 @@ module.exports =
 			return ErrorsController.notFound(req, res)
 			return ErrorsController.notFound(req, res)
 		res.render "subscriptions/group/successful_join",
 		res.render "subscriptions/group/successful_join",
 			title: "Sucessfully joined group"
 			title: "Sucessfully joined group"
-			licenceName:licence.name	
+			licenceName:licence.name
 
 
 	exportGroupCsv: (req, res)->
 	exportGroupCsv: (req, res)->
-		user_id = req.session.user._id
+		user_id = AuthenticationController.getLoggedInUserId(req)
 		logger.log user_id: user_id, "exporting group csv"
 		logger.log user_id: user_id, "exporting group csv"
 		SubscriptionLocator.getUsersSubscription user_id, (err, subscription)->
 		SubscriptionLocator.getUsersSubscription user_id, (err, subscription)->
 			if !subscription.groupPlan
 			if !subscription.groupPlan

+ 12 - 11
services/web/app/coffee/Features/Tags/TagsController.coffee

@@ -1,48 +1,49 @@
 TagsHandler = require("./TagsHandler")
 TagsHandler = require("./TagsHandler")
 logger = require("logger-sharelatex")
 logger = require("logger-sharelatex")
+AuthenticationController = require('../Authentication/AuthenticationController')
 
 
 module.exports =
 module.exports =
 	getAllTags: (req, res, next)->
 	getAllTags: (req, res, next)->
-		user_id = req.session.user._id
+		user_id = AuthenticationController.getLoggedInUserId(req)
 		logger.log {user_id}, "getting tags"
 		logger.log {user_id}, "getting tags"
 		TagsHandler.getAllTags user_id, (error, allTags)->
 		TagsHandler.getAllTags user_id, (error, allTags)->
 			return next(error) if error?
 			return next(error) if error?
 			res.json(allTags)
 			res.json(allTags)
-	
+
 	createTag: (req, res, next) ->
 	createTag: (req, res, next) ->
-		user_id = req.session.user._id
+		user_id = AuthenticationController.getLoggedInUserId(req)
 		name = req.body.name
 		name = req.body.name
 		logger.log {user_id, name}, "creating tag"
 		logger.log {user_id, name}, "creating tag"
 		TagsHandler.createTag user_id, name, (error, tag) ->
 		TagsHandler.createTag user_id, name, (error, tag) ->
 			return next(error) if error?
 			return next(error) if error?
 			res.json(tag)
 			res.json(tag)
-	
+
 	addProjectToTag: (req, res, next) ->
 	addProjectToTag: (req, res, next) ->
-		user_id = req.session.user._id
+		user_id = AuthenticationController.getLoggedInUserId(req)
 		{tag_id, project_id} = req.params
 		{tag_id, project_id} = req.params
 		logger.log {user_id, tag_id, project_id}, "adding tag to project"
 		logger.log {user_id, tag_id, project_id}, "adding tag to project"
 		TagsHandler.addProjectToTag user_id, tag_id, project_id, (error) ->
 		TagsHandler.addProjectToTag user_id, tag_id, project_id, (error) ->
 			return next(error) if error?
 			return next(error) if error?
 			res.status(204).end()
 			res.status(204).end()
-	
+
 	removeProjectFromTag: (req, res, next) ->
 	removeProjectFromTag: (req, res, next) ->
-		user_id = req.session.user._id
+		user_id = AuthenticationController.getLoggedInUserId(req)
 		{tag_id, project_id} = req.params
 		{tag_id, project_id} = req.params
 		logger.log {user_id, tag_id, project_id}, "removing tag from project"
 		logger.log {user_id, tag_id, project_id}, "removing tag from project"
 		TagsHandler.removeProjectFromTag user_id, tag_id, project_id, (error) ->
 		TagsHandler.removeProjectFromTag user_id, tag_id, project_id, (error) ->
 			return next(error) if error?
 			return next(error) if error?
 			res.status(204).end()
 			res.status(204).end()
-	
+
 	deleteTag: (req, res, next) ->
 	deleteTag: (req, res, next) ->
-		user_id = req.session.user._id
+		user_id = AuthenticationController.getLoggedInUserId(req)
 		tag_id = req.params.tag_id
 		tag_id = req.params.tag_id
 		logger.log {user_id, tag_id}, "deleting tag"
 		logger.log {user_id, tag_id}, "deleting tag"
 		TagsHandler.deleteTag user_id, tag_id, (error) ->
 		TagsHandler.deleteTag user_id, tag_id, (error) ->
 			return next(error) if error?
 			return next(error) if error?
 			res.status(204).end()
 			res.status(204).end()
-	
+
 	renameTag: (req, res, next) ->
 	renameTag: (req, res, next) ->
-		user_id = req.session.user._id
+		user_id = AuthenticationController.getLoggedInUserId(req)
 		tag_id = req.params.tag_id
 		tag_id = req.params.tag_id
 		name = req.body?.name
 		name = req.body?.name
 		if !name?
 		if !name?

+ 13 - 14
services/web/app/coffee/Features/TrackChanges/TrackChangesController.coffee

@@ -5,17 +5,16 @@ AuthenticationController = require "../Authentication/AuthenticationController"
 
 
 module.exports = TrackChangesController =
 module.exports = TrackChangesController =
 	proxyToTrackChangesApi: (req, res, next = (error) ->) ->
 	proxyToTrackChangesApi: (req, res, next = (error) ->) ->
-		AuthenticationController.getLoggedInUserId req, (error, user_id) ->
-			return next(error) if error?
-			url = settings.apis.trackchanges.url + req.url
-			logger.log url: url, "proxying to track-changes api"
-			getReq = request(
-				url: url
-				method: req.method
-				headers:
-					"X-User-Id": user_id
-			)
-			getReq.pipe(res)
-			getReq.on "error", (error) ->
-				logger.error err: error, "track-changes API error"
-				next(error)
+		user_id = AuthenticationController.getLoggedInUserId req
+		url = settings.apis.trackchanges.url + req.url
+		logger.log url: url, "proxying to track-changes api"
+		getReq = request(
+			url: url
+			method: req.method
+			headers:
+				"X-User-Id": user_id
+		)
+		getReq.pipe(res)
+		getReq.on "error", (error) ->
+			logger.error err: error, "track-changes API error"
+			next(error)

+ 4 - 6
services/web/app/coffee/Features/Uploads/ProjectUploadController.coffee

@@ -4,11 +4,12 @@ fs      = require "fs"
 Path    = require "path"
 Path    = require "path"
 FileSystemImportManager = require "./FileSystemImportManager"
 FileSystemImportManager = require "./FileSystemImportManager"
 ProjectUploadManager    = require "./ProjectUploadManager"
 ProjectUploadManager    = require "./ProjectUploadManager"
+AuthenticationController = require('../Authentication/AuthenticationController')
 
 
 module.exports = ProjectUploadController =
 module.exports = ProjectUploadController =
 	uploadProject: (req, res, next) ->
 	uploadProject: (req, res, next) ->
 		timer = new metrics.Timer("project-upload")
 		timer = new metrics.Timer("project-upload")
-		user_id = req.session.user._id
+		user_id = AuthenticationController.getLoggedInUserId(req)
 		{originalname, path} = req.files.qqfile
 		{originalname, path} = req.files.qqfile
 		name = Path.basename(originalname, ".zip")
 		name = Path.basename(originalname, ".zip")
 		ProjectUploadManager.createProjectFromZipArchive user_id, name, path, (error, project) ->
 		ProjectUploadManager.createProjectFromZipArchive user_id, name, path, (error, project) ->
@@ -24,7 +25,7 @@ module.exports = ProjectUploadController =
 					project: project._id, file_path: path, file_name: name,
 					project: project._id, file_path: path, file_name: name,
 					"uploaded project"
 					"uploaded project"
 				res.send success: true, project_id: project._id
 				res.send success: true, project_id: project._id
-	
+
 	uploadFile: (req, res, next) ->
 	uploadFile: (req, res, next) ->
 		timer = new metrics.Timer("file-upload")
 		timer = new metrics.Timer("file-upload")
 		name = req.files.qqfile?.originalname
 		name = req.files.qqfile?.originalname
@@ -35,7 +36,7 @@ module.exports = ProjectUploadController =
 			logger.err project_id:project_id, name:name, "bad name when trying to upload file"
 			logger.err project_id:project_id, name:name, "bad name when trying to upload file"
 			return res.send success: false
 			return res.send success: false
 		logger.log folder_id:folder_id, project_id:project_id, "getting upload file request"
 		logger.log folder_id:folder_id, project_id:project_id, "getting upload file request"
-		user_id = req.session.user._id
+		user_id = AuthenticationController.getLoggedInUserId(req)
 		FileSystemImportManager.addEntity user_id, project_id, folder_id, name, path, true, (error, entity) ->
 		FileSystemImportManager.addEntity user_id, project_id, folder_id, name, path, true, (error, entity) ->
 			fs.unlink path, ->
 			fs.unlink path, ->
 			timer.done()
 			timer.done()
@@ -50,6 +51,3 @@ module.exports = ProjectUploadController =
 					project_id: project_id, file_path: path, file_name: name, folder_id: folder_id
 					project_id: project_id, file_path: path, file_name: name, folder_id: folder_id
 					"uploaded file"
 					"uploaded file"
 				res.send success: true, entity_id: entity?._id
 				res.send success: true, entity_id: entity?._id
-
-
-

+ 17 - 14
services/web/app/coffee/Features/User/UserController.coffee

@@ -8,6 +8,7 @@ logger = require("logger-sharelatex")
 metrics = require("../../infrastructure/Metrics")
 metrics = require("../../infrastructure/Metrics")
 Url = require("url")
 Url = require("url")
 AuthenticationManager = require("../Authentication/AuthenticationManager")
 AuthenticationManager = require("../Authentication/AuthenticationManager")
+AuthenticationController = require('../Authentication/AuthenticationController')
 UserSessionsManager = require("./UserSessionsManager")
 UserSessionsManager = require("./UserSessionsManager")
 UserUpdater = require("./UserUpdater")
 UserUpdater = require("./UserUpdater")
 settings = require "settings-sharelatex"
 settings = require "settings-sharelatex"
@@ -15,20 +16,21 @@ settings = require "settings-sharelatex"
 module.exports = UserController =
 module.exports = UserController =
 
 
 	deleteUser: (req, res)->
 	deleteUser: (req, res)->
-		user_id = req.session.user._id
+		user_id = AuthenticationController.getLoggedInUserId(req)
 		UserDeleter.deleteUser user_id, (err)->
 		UserDeleter.deleteUser user_id, (err)->
 			if !err?
 			if !err?
 				req.session?.destroy()
 				req.session?.destroy()
 			res.sendStatus(200)
 			res.sendStatus(200)
 
 
 	unsubscribe: (req, res)->
 	unsubscribe: (req, res)->
-		UserLocator.findById req.session.user._id, (err, user)->
+		user_id = AuthenticationController.getLoggedInUserId(req)
+		UserLocator.findById user_id, (err, user)->
 			newsLetterManager.unsubscribe user, ->
 			newsLetterManager.unsubscribe user, ->
 				res.send()
 				res.send()
 
 
 	updateUserSettings : (req, res)->
 	updateUserSettings : (req, res)->
-		logger.log user: req.session.user, "updating account settings"
-		user_id = req.session.user._id
+		user_id = AuthenticationController.getLoggedInUserId(req)
+		logger.log user: user_id, "updating account settings"
 		User.findById user_id, (err, user)->
 		User.findById user_id, (err, user)->
 			if err? or !user?
 			if err? or !user?
 				logger.err err:err, user_id:user_id, "problem updaing user settings"
 				logger.err err:err, user_id:user_id, "problem updaing user settings"
@@ -73,7 +75,7 @@ module.exports = UserController =
 							if err?
 							if err?
 								logger.err err:err, user_id:user_id, "error getting user for email update"
 								logger.err err:err, user_id:user_id, "error getting user for email update"
 								return res.send 500
 								return res.send 500
-							req.session.user.email = user.email
+							req.user.email = user.email
 							UserHandler.populateGroupLicenceInvite user, (err)-> #need to refresh this in the background
 							UserHandler.populateGroupLicenceInvite user, (err)-> #need to refresh this in the background
 								if err?
 								if err?
 									logger.err err:err, "error populateGroupLicenceInvite"
 									logger.err err:err, "error populateGroupLicenceInvite"
@@ -83,13 +85,13 @@ module.exports = UserController =
 		metrics.inc "user.logout"
 		metrics.inc "user.logout"
 		logger.log user: req?.session?.user, "logging out"
 		logger.log user: req?.session?.user, "logging out"
 		sessionId = req.sessionID
 		sessionId = req.sessionID
-		user = req?.session?.user
-		req.logout?()  # passport logout
-		req.session.destroy (err)->
-			if err
-				logger.err err: err, 'error destorying session'
-			UserSessionsManager.untrackSession(user, sessionId)
-			res.redirect '/login'
+		AuthenticationController.getLoggedInUser req, (err, user) ->
+			req.logout?()  # passport logout
+			req.session.destroy (err)->
+				if err
+					logger.err err: err, 'error destorying session'
+				UserSessionsManager.untrackSession(user, sessionId)
+				res.redirect '/login'
 
 
 	register : (req, res, next = (error) ->)->
 	register : (req, res, next = (error) ->)->
 		email = req.body.email
 		email = req.body.email
@@ -106,10 +108,11 @@ module.exports = UserController =
 	changePassword : (req, res, next = (error) ->)->
 	changePassword : (req, res, next = (error) ->)->
 		metrics.inc "user.password-change"
 		metrics.inc "user.password-change"
 		oldPass = req.body.currentPassword
 		oldPass = req.body.currentPassword
-		AuthenticationManager.authenticate {_id:req.session.user._id}, oldPass, (err, user)->
+		user_id = AuthenticationController.getLoggedInUserId(req)
+		AuthenticationManager.authenticate {_id:user_id}, oldPass, (err, user)->
 			return next(err) if err?
 			return next(err) if err?
 			if(user)
 			if(user)
-				logger.log user: req.session.user, "changing password"
+				logger.log user: user._id, "changing password"
 				newPassword1 = req.body.newPassword1
 				newPassword1 = req.body.newPassword1
 				newPassword2 = req.body.newPassword2
 				newPassword2 = req.body.newPassword2
 				if newPassword1 != newPassword2
 				if newPassword1 != newPassword2

+ 6 - 4
services/web/app/coffee/Features/User/UserPagesController.coffee

@@ -4,6 +4,7 @@ ErrorController = require("../Errors/ErrorController")
 logger = require("logger-sharelatex")
 logger = require("logger-sharelatex")
 Settings = require("settings-sharelatex")
 Settings = require("settings-sharelatex")
 fs = require('fs')
 fs = require('fs')
+AuthenticationController = require('../Authentication/AuthenticationController')
 
 
 module.exports =
 module.exports =
 
 
@@ -22,14 +23,14 @@ module.exports =
 			sharedProjectData: sharedProjectData
 			sharedProjectData: sharedProjectData
 			newTemplateData: newTemplateData
 			newTemplateData: newTemplateData
 			new_email:req.query.new_email || ""
 			new_email:req.query.new_email || ""
-	
+
 	activateAccountPage: (req, res) ->
 	activateAccountPage: (req, res) ->
 		# An 'activation' is actually just a password reset on an account that
 		# An 'activation' is actually just a password reset on an account that
 		# was set with a random password originally.
 		# was set with a random password originally.
 		logger.log query:req.query, "activiate account page called"
 		logger.log query:req.query, "activiate account page called"
 		if !req.query?.user_id? or !req.query?.token?
 		if !req.query?.user_id? or !req.query?.token?
 			return ErrorController.notFound(req, res)
 			return ErrorController.notFound(req, res)
-			
+
 		UserGetter.getUser req.query.user_id, {email: 1, loginCount: 1}, (error, user) ->
 		UserGetter.getUser req.query.user_id, {email: 1, loginCount: 1}, (error, user) ->
 			return next(error) if error?
 			return next(error) if error?
 			if !user
 			if !user
@@ -53,8 +54,9 @@ module.exports =
 			email: req.query.email
 			email: req.query.email
 
 
 	settingsPage : (req, res, next)->
 	settingsPage : (req, res, next)->
-		logger.log user: req.session.user, "loading settings page"
-		UserLocator.findById req.session.user._id, (err, user)->
+		user_id = AuthenticationController.getLoggedInUserId(req)
+		logger.log user: user_id, "loading settings page"
+		UserLocator.findById user_id, (err, user)->
 			return next(err) if err?
 			return next(err) if err?
 			res.render 'user/settings',
 			res.render 'user/settings',
 				title:'account_settings'
 				title:'account_settings'

+ 15 - 16
services/web/app/coffee/infrastructure/ExpressLocals.coffee

@@ -5,6 +5,7 @@ Settings = require('settings-sharelatex')
 SubscriptionFormatters = require('../Features/Subscription/SubscriptionFormatters')
 SubscriptionFormatters = require('../Features/Subscription/SubscriptionFormatters')
 querystring = require('querystring')
 querystring = require('querystring')
 SystemMessageManager = require("../Features/SystemMessages/SystemMessageManager")
 SystemMessageManager = require("../Features/SystemMessages/SystemMessageManager")
+AuthenticationController = require("../Features/Authentication/AuthenticationController")
 _ = require("underscore")
 _ = require("underscore")
 Modules = require "./Modules"
 Modules = require "./Modules"
 Url = require "url"
 Url = require "url"
@@ -59,7 +60,7 @@ module.exports = (app, webRouter, apiRouter)->
 		res.locals.session = req.session
 		res.locals.session = req.session
 		next()
 		next()
 
 
-	webRouter.use (req, res, next)-> 
+	webRouter.use (req, res, next)->
 
 
 		cdnBlocked = req.query.nocdn == 'true' or req.session.cdnBlocked
 		cdnBlocked = req.query.nocdn == 'true' or req.session.cdnBlocked
 
 
@@ -77,7 +78,7 @@ module.exports = (app, webRouter, apiRouter)->
 			staticFilesBase = Settings.cdn?.web?.darkHost
 			staticFilesBase = Settings.cdn?.web?.darkHost
 		else
 		else
 			staticFilesBase = ""
 			staticFilesBase = ""
-		
+
 		res.locals.jsPath = jsPath
 		res.locals.jsPath = jsPath
 		res.locals.fullJsPath = Url.resolve(staticFilesBase, jsPath)
 		res.locals.fullJsPath = Url.resolve(staticFilesBase, jsPath)
 
 
@@ -86,7 +87,7 @@ module.exports = (app, webRouter, apiRouter)->
 			path = Path.join(jsPath, jsFile)
 			path = Path.join(jsPath, jsFile)
 
 
 			doFingerPrint = opts.fingerprint != false
 			doFingerPrint = opts.fingerprint != false
-			
+
 			if !opts.qs?
 			if !opts.qs?
 				opts.qs = {}
 				opts.qs = {}
 
 
@@ -95,7 +96,7 @@ module.exports = (app, webRouter, apiRouter)->
 
 
 			if opts.cdn != false
 			if opts.cdn != false
 				path = Url.resolve(staticFilesBase, path)
 				path = Url.resolve(staticFilesBase, path)
-				
+
 			qs = querystring.stringify(opts.qs)
 			qs = querystring.stringify(opts.qs)
 
 
 			if qs? and qs.length > 0
 			if qs? and qs.length > 0
@@ -115,7 +116,7 @@ module.exports = (app, webRouter, apiRouter)->
 
 
 
 
 
 
-	webRouter.use (req, res, next)-> 
+	webRouter.use (req, res, next)->
 		res.locals.settings = Settings
 		res.locals.settings = Settings
 		next()
 		next()
 
 
@@ -143,7 +144,7 @@ module.exports = (app, webRouter, apiRouter)->
 			return formatedPrivileges[privilegeLevel] || "Private"
 			return formatedPrivileges[privilegeLevel] || "Private"
 		next()
 		next()
 
 
-	webRouter.use (req, res, next)-> 
+	webRouter.use (req, res, next)->
 		res.locals.buildReferalUrl = (referal_medium) ->
 		res.locals.buildReferalUrl = (referal_medium) ->
 			url = Settings.siteUrl
 			url = Settings.siteUrl
 			if req.session? and req.session.user? and req.session.user.referal_id?
 			if req.session? and req.session.user? and req.session.user.referal_id?
@@ -167,7 +168,7 @@ module.exports = (app, webRouter, apiRouter)->
 			return ""
 			return ""
 
 
 		res.locals.getLoggedInUserId = ->
 		res.locals.getLoggedInUserId = ->
-			return req.session.user?._id
+			return AuthenticationController.getLoggedInUserId(req)
 		next()
 		next()
 
 
 	webRouter.use (req, res, next) ->
 	webRouter.use (req, res, next) ->
@@ -179,11 +180,11 @@ module.exports = (app, webRouter, apiRouter)->
 			return req.query?[field]
 			return req.query?[field]
 		next()
 		next()
 
 
-	webRouter.use (req, res, next)-> 
+	webRouter.use (req, res, next)->
 		res.locals.fingerprint = getFingerprint
 		res.locals.fingerprint = getFingerprint
 		next()
 		next()
 
 
-	webRouter.use (req, res, next)-> 
+	webRouter.use (req, res, next)->
 		res.locals.formatPrice = SubscriptionFormatters.formatPrice
 		res.locals.formatPrice = SubscriptionFormatters.formatPrice
 		next()
 		next()
 
 
@@ -193,11 +194,11 @@ module.exports = (app, webRouter, apiRouter)->
 		next()
 		next()
 
 
 	webRouter.use (req, res, next)->
 	webRouter.use (req, res, next)->
-		if req.session.user?
+		if req.user?
 			res.locals.user =
 			res.locals.user =
-				email: req.session.user.email
-				first_name: req.session.user.first_name
-				last_name: req.session.user.last_name
+				email: req.user.email
+				first_name: req.user.first_name
+				last_name: req.user.last_name
 			if req.session.justRegistered
 			if req.session.justRegistered
 				res.locals.justRegistered = true
 				res.locals.justRegistered = true
 				delete req.session.justRegistered
 				delete req.session.justRegistered
@@ -223,7 +224,7 @@ module.exports = (app, webRouter, apiRouter)->
 			res.locals.nav[key] = _.clone(Settings.nav[key])
 			res.locals.nav[key] = _.clone(Settings.nav[key])
 		res.locals.templates = Settings.templateLinks
 		res.locals.templates = Settings.templateLinks
 		next()
 		next()
-		
+
 	webRouter.use (req, res, next) ->
 	webRouter.use (req, res, next) ->
 		SystemMessageManager.getMessages (error, messages = []) ->
 		SystemMessageManager.getMessages (error, messages = []) ->
 			res.locals.systemMessages = messages
 			res.locals.systemMessages = messages
@@ -246,5 +247,3 @@ module.exports = (app, webRouter, apiRouter)->
 		res.locals.moduleIncludes = Modules.moduleIncludes
 		res.locals.moduleIncludes = Modules.moduleIncludes
 		res.locals.moduleIncludesAvailable = Modules.moduleIncludesAvailable
 		res.locals.moduleIncludesAvailable = Modules.moduleIncludesAvailable
 		next()
 		next()
-
-