From ab2c1e82fb22866e53728c2ebe4c1ffb2bf8e986 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Mon, 5 Sep 2016 15:58:31 +0100 Subject: [PATCH] WIP: refactor --- .../Analytics/AnalyticsController.coffee | 4 +- .../AuthenticationController.coffee | 135 ++++++++++-------- .../AuthorizationMiddlewear.coffee | 27 ++-- .../Features/Chat/ChatController.coffee | 8 +- .../CollaboratorsInviteController.coffee | 127 ++++++++-------- .../Features/Compile/CompileController.coffee | 62 ++++---- .../Contacts/ContactController.coffee | 47 +++--- .../NotificationsController.coffee | 8 +- .../Features/Project/ProjectController.coffee | 117 +++++++-------- .../Features/Referal/ReferalController.coffee | 6 +- .../Features/Referal/ReferalMiddleware.coffee | 7 +- .../Security/RateLimiterMiddlewear.coffee | 14 +- .../Spelling/SpellingController.coffee | 4 +- .../StaticPages/HomeController.coffee | 5 +- .../SubscriptionController.coffee | 4 +- .../SubscriptionGroupController.coffee | 40 +++--- .../Features/Tags/TagsController.coffee | 23 +-- .../TrackChangesController.coffee | 27 ++-- .../Uploads/ProjectUploadController.coffee | 10 +- .../Features/User/UserController.coffee | 31 ++-- .../Features/User/UserPagesController.coffee | 10 +- .../infrastructure/ExpressLocals.coffee | 31 ++-- 22 files changed, 390 insertions(+), 357 deletions(-) diff --git a/services/web/app/coffee/Features/Analytics/AnalyticsController.coffee b/services/web/app/coffee/Features/Analytics/AnalyticsController.coffee index a49a419e07..4d5239ac45 100644 --- a/services/web/app/coffee/Features/Analytics/AnalyticsController.coffee +++ b/services/web/app/coffee/Features/Analytics/AnalyticsController.coffee @@ -1,7 +1,7 @@ -AnalyticsManager = require "./AnalyticsManager" +AnalyticsManager = equire "./AnalyticsManager" module.exports = AnalyticsController = recordEvent: (req, res, next) -> AnalyticsManager.recordEvent req.session?.user?._id, req.params.event, req.body, (error) -> return next(error) if error? - res.send 204 \ No newline at end of file + res.send 204 diff --git a/services/web/app/coffee/Features/Authentication/AuthenticationController.coffee b/services/web/app/coffee/Features/Authentication/AuthenticationController.coffee index 4e358cc2cd..572ebe5b3f 100644 --- a/services/web/app/coffee/Features/Authentication/AuthenticationController.coffee +++ b/services/web/app/coffee/Features/Authentication/AuthenticationController.coffee @@ -14,8 +14,8 @@ Analytics = require "../Analytics/AnalyticsManager" 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) -> console.log ">> serialize", user._id @@ -65,60 +65,38 @@ module.exports = AuthenticationController = logger.log email: email, "failed log in" 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? - 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 - callback null, null + return null + # TODO: perhaps should produce an error if the current user is not present getLoggedInUser: (req, callback = (error, user) ->) -> if req.session?.user?._id? query = req.session.user._id else return callback null, null - UserGetter.getUser query, callback + # omit sensitive information + UserGetter.getUser query, {hashedPassword: false, refProviders: false}, callback requireLogin: () -> doRequest = (req, res, next = (error) ->) -> console.log ">>>>", req.currentUser() - if !req.session.user? + if !AuthenticationController.isUserLoggedIn()? AuthenticationController._redirectToLoginOrRegisterPage(req, res) else - req.user = req.session.user return next() return doRequest @@ -133,7 +111,7 @@ module.exports = AuthenticationController = if req.headers['authorization']? return AuthenticationController.httpAuth(req, res, next) - else if req.session.user? + else if AuthenticationController.isUserLoggedIn()? return next() else 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" 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 + # 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 + # req.session.user = lightUser - UserSessionsManager.trackSession(user, req.sessionID, () ->) - callback() + # 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' diff --git a/services/web/app/coffee/Features/Authorization/AuthorizationMiddlewear.coffee b/services/web/app/coffee/Features/Authorization/AuthorizationMiddlewear.coffee index 4888db0c8a..f321b015f6 100644 --- a/services/web/app/coffee/Features/Authorization/AuthorizationMiddlewear.coffee +++ b/services/web/app/coffee/Features/Authorization/AuthorizationMiddlewear.coffee @@ -3,6 +3,7 @@ async = require "async" logger = require "logger-sharelatex" ObjectId = require("mongojs").ObjectId Errors = require "../Errors/Errors" +AuthenticationController = require "../Authentication/AuthenticationController" module.exports = AuthorizationMiddlewear = ensureUserCanReadMultipleProjects: (req, res, next) -> @@ -20,7 +21,7 @@ module.exports = AuthorizationMiddlewear = AuthorizationMiddlewear.redirectToRestricted req, res, next else next() - + ensureUserCanReadProject: (req, res, next) -> AuthorizationMiddlewear._getUserAndProjectId req, (error, user_id, project_id) -> return next(error) if error? @@ -32,7 +33,7 @@ module.exports = AuthorizationMiddlewear = else logger.log {user_id, project_id}, "denying user read access to project" AuthorizationMiddlewear.redirectToRestricted req, res, next - + ensureUserCanWriteProjectSettings: (req, res, next) -> AuthorizationMiddlewear._getUserAndProjectId req, (error, user_id, project_id) -> return next(error) if error? @@ -44,7 +45,7 @@ module.exports = AuthorizationMiddlewear = else logger.log {user_id, project_id}, "denying user write access to project settings" AuthorizationMiddlewear.redirectToRestricted req, res, next - + ensureUserCanWriteProjectContent: (req, res, next) -> AuthorizationMiddlewear._getUserAndProjectId req, (error, user_id, project_id) -> return next(error) if error? @@ -56,7 +57,7 @@ module.exports = AuthorizationMiddlewear = else logger.log {user_id, project_id}, "denying user write access to project settings" AuthorizationMiddlewear.redirectToRestricted req, res, next - + ensureUserCanAdminProject: (req, res, next) -> AuthorizationMiddlewear._getUserAndProjectId req, (error, user_id, project_id) -> return next(error) if error? @@ -68,7 +69,7 @@ module.exports = AuthorizationMiddlewear = else logger.log {user_id, project_id}, "denying user admin access to project" AuthorizationMiddlewear.redirectToRestricted req, res, next - + ensureUserIsSiteAdmin: (req, res, next) -> AuthorizationMiddlewear._getUserId req, (error, user_id) -> return next(error) if error? @@ -90,22 +91,18 @@ module.exports = AuthorizationMiddlewear = AuthorizationMiddlewear._getUserId req, (error, user_id) -> return callback(error) if error? callback(null, user_id, project_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) -> res.redirect "/restricted" - + restricted : (req, res, next)-> - if req.session.user? + if AuthenticationController.isUserLoggedIn()? res.render 'user/restricted', title:'restricted' else logger.log "user not logged in and trying to access #{req.url}, being redirected to login" res.redirect '/register' - \ No newline at end of file diff --git a/services/web/app/coffee/Features/Chat/ChatController.coffee b/services/web/app/coffee/Features/Chat/ChatController.coffee index ef3cbf94fc..35c280712a 100644 --- a/services/web/app/coffee/Features/Chat/ChatController.coffee +++ b/services/web/app/coffee/Features/Chat/ChatController.coffee @@ -1,14 +1,18 @@ ChatHandler = require("./ChatHandler") EditorRealTimeController = require("../Editor/EditorRealTimeController") logger = require("logger-sharelatex") +AuthenticationController = require('../Authentication/AuthenticationController') module.exports = - sendMessage: (req, res)-> + sendMessage: (req, res, next)-> project_id = req.params.Project_id - user_id = req.session.user._id 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)-> if err? logger.err err:err, project_id:project_id, user_id:user_id, messageContent:messageContent, "problem sending message to chat api" diff --git a/services/web/app/coffee/Features/Collaborators/CollaboratorsInviteController.coffee b/services/web/app/coffee/Features/Collaborators/CollaboratorsInviteController.coffee index 4f8daf4bdb..cfc6c4b08d 100644 --- a/services/web/app/coffee/Features/Collaborators/CollaboratorsInviteController.coffee +++ b/services/web/app/coffee/Features/Collaborators/CollaboratorsInviteController.coffee @@ -8,6 +8,7 @@ EmailHelper = require "../Helpers/EmailHelper" EditorRealTimeController = require("../Editor/EditorRealTimeController") NotificationsBuilder = require("../Notifications/NotificationsBuilder") AnalyticsManger = require("../Analytics/AnalyticsManager") +AuthenticationController = require("../Authentication/AuthenticationController") module.exports = CollaboratorsInviteController = @@ -23,26 +24,27 @@ module.exports = CollaboratorsInviteController = inviteToProject: (req, res, next) -> projectId = req.params.Project_id 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) -> projectId = req.params.Project_id @@ -58,67 +60,70 @@ module.exports = CollaboratorsInviteController = resendInvite: (req, res, next) -> projectId = req.params.Project_id inviteId = req.params.invite_id - sendingUser = req.session.user 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) -> projectId = req.params.Project_id token = req.params.token - currentUser = req.session.user _renderInvalidPage = () -> logger.log {projectId, token}, "invite not valid, rendering not-valid page" res.render "project/invite/not-valid", {title: "Invalid Invite"} # 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? - logger.err {projectId, token}, "error getting invite by token" + logger.err {err, projectId}, "error checking if user is member of project" 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? - logger.err {err, projectId}, "error getting project owner" + logger.err {projectId, token}, "error getting invite by token" 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() - # 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? - logger.err {err, projectId}, "error getting project" + logger.err {err, projectId}, "error getting project owner" return next(err) - if !project? - logger.log {projectId}, "no project found" + if !owner? + logger.log {projectId}, "no project owner found" 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) -> projectId = req.params.Project_id inviteId = req.params.invite_id {token} = req.body - currentUser = req.session.user 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}" diff --git a/services/web/app/coffee/Features/Compile/CompileController.coffee b/services/web/app/coffee/Features/Compile/CompileController.coffee index 688b746830..4a23431574 100755 --- a/services/web/app/coffee/Features/Compile/CompileController.coffee +++ b/services/web/app/coffee/Features/Compile/CompileController.coffee @@ -16,53 +16,53 @@ module.exports = CompileController = res.setTimeout(5 * 60 * 1000) project_id = req.params.Project_id 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? - 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) ->) -> 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? - 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) -> # callback with user_id if per-user, undefined otherwise if not Settings.disablePerUserCompiles - AuthenticationController.getLoggedInUserId req, callback # -> (error, user_id) + user_id = AuthenticationController.getLoggedInUserId req + return callback(null, user_id) else callback() # do a per-project compile, not per-user _downloadAsUser: (req, callback) -> # callback with user_id if per-user, undefined otherwise if not Settings.disablePerUserCompiles - AuthenticationController.getLoggedInUserId req, callback # -> (error, user_id) + user_id = AuthenticationController.getLoggedInUserId req + return callback(null, user_id) else callback() # do a per-project compile, not per-user diff --git a/services/web/app/coffee/Features/Contacts/ContactController.coffee b/services/web/app/coffee/Features/Contacts/ContactController.coffee index a62c22bbf2..b3c2f7d02b 100644 --- a/services/web/app/coffee/Features/Contacts/ContactController.coffee +++ b/services/web/app/coffee/Features/Contacts/ContactController.coffee @@ -6,33 +6,32 @@ Modules = require "../../infrastructure/Modules" module.exports = ContactsController = 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? - 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? - UserGetter.getUsers contact_ids, { - email: 1, first_name: 1, last_name: 1, holdingAccount: 1 - }, (error, contacts) -> - 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()] - # 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 - }) - + # 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? + contacts = contacts.concat(additional_contacts...) + res.send({ + contacts: contacts + }) + _formatContact: (contact) -> return { id: contact._id?.toString() diff --git a/services/web/app/coffee/Features/Notifications/NotificationsController.coffee b/services/web/app/coffee/Features/Notifications/NotificationsController.coffee index c4931f5327..5b83a60248 100644 --- a/services/web/app/coffee/Features/Notifications/NotificationsController.coffee +++ b/services/web/app/coffee/Features/Notifications/NotificationsController.coffee @@ -1,18 +1,20 @@ NotificationsHandler = require("./NotificationsHandler") +AuthenticationController = require("../Authentication/AuthenticationController") logger = require("logger-sharelatex") _ = require("underscore") module.exports = 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) return notification res.send(unreadNotifications) markNotificationAsRead: (req, res)-> - user_id = req.session.user._id + user_id = AuthenticationController.getLoggedInUserId(req) notification_id = req.params.notification_id NotificationsHandler.markAsRead user_id, notification_id, -> res.send() diff --git a/services/web/app/coffee/Features/Project/ProjectController.coffee b/services/web/app/coffee/Features/Project/ProjectController.coffee index d28b5ca868..9c016b7b2e 100644 --- a/services/web/app/coffee/Features/Project/ProjectController.coffee +++ b/services/web/app/coffee/Features/Project/ProjectController.coffee @@ -18,6 +18,7 @@ InactiveProjectManager = require("../InactiveData/InactiveProjectManager") ProjectUpdateHandler = require("./ProjectUpdateHandler") ProjectGetter = require("./ProjectGetter") PrivilegeLevels = require("../Authorization/PrivilegeLevels") +AuthenticationController = require("../Authentication/AuthenticationController") module.exports = ProjectController = @@ -88,32 +89,34 @@ module.exports = ProjectController = project_id = req.params.Project_id projectName = req.body.projectName logger.log project_id:project_id, projectName:projectName, "cloning project" - if !req.session.user? + if !AuthenticationController.isUserLoggedIn()? 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)-> - user = req.session.user + user_id = AuthenticationController.getLoggedInUserId(req) projectName = req.body.projectName?.trim() 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 [ (cb)-> if template == 'example' - projectCreationHandler.createExampleProject user._id, projectName, cb + projectCreationHandler.createExampleProject user_id, projectName, cb else - projectCreationHandler.createBasicProject user._id, projectName, cb + projectCreationHandler.createBasicProject user_id, projectName, cb ], (err, project)-> 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 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} @@ -131,51 +134,53 @@ module.exports = ProjectController = projectListPage: (req, res, next)-> 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? + 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] - } + 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 + 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() + res.render 'project/list', viewModel + timer.done() loadEditor: (req, res, next)-> @@ -183,8 +188,8 @@ module.exports = ProjectController = if !Settings.editorIsOpen 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 else anonymous = true diff --git a/services/web/app/coffee/Features/Referal/ReferalController.coffee b/services/web/app/coffee/Features/Referal/ReferalController.coffee index fbe812a22e..1c8cef03b4 100644 --- a/services/web/app/coffee/Features/Referal/ReferalController.coffee +++ b/services/web/app/coffee/Features/Referal/ReferalController.coffee @@ -1,9 +1,11 @@ logger = require('logger-sharelatex') ReferalHandler = require('./ReferalHandler') +AuthenticationController = require('../Authentication/AuthenticationController') -module.exports = +module.exports = 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", title: "bonus_please_recommend_us" refered_users: refered_users diff --git a/services/web/app/coffee/Features/Referal/ReferalMiddleware.coffee b/services/web/app/coffee/Features/Referal/ReferalMiddleware.coffee index c6f02d34bf..18e5a34d39 100644 --- a/services/web/app/coffee/Features/Referal/ReferalMiddleware.coffee +++ b/services/web/app/coffee/Features/Referal/ReferalMiddleware.coffee @@ -1,11 +1,12 @@ User = require("../../models/User").User +AuthenticationController = require('../Authentication/AuthenticationController') module.exports = RefererMiddleware = 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? - req.session.user.referal_id = user.referal_id + req.user.referal_id = user.referal_id next() else next() diff --git a/services/web/app/coffee/Features/Security/RateLimiterMiddlewear.coffee b/services/web/app/coffee/Features/Security/RateLimiterMiddlewear.coffee index dc71da09fc..f486e94493 100644 --- a/services/web/app/coffee/Features/Security/RateLimiterMiddlewear.coffee +++ b/services/web/app/coffee/Features/Security/RateLimiterMiddlewear.coffee @@ -1,24 +1,22 @@ RateLimiter = require "../../infrastructure/RateLimiter" logger = require "logger-sharelatex" +AuthenticationController = require('../Authentication/AuthenticationController') module.exports = RateLimiterMiddlewear = ### 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 parameters in the request URL, e.g.: - + app.get "/project/:project_id", RateLimiterMiddlewear.rateLimit(endpointName: "open-editor", params: ["project_id"]) - + will rate limit each project_id separately. - + Unique clients are identified by user_id if logged in, and IP address if not. ### rateLimit: (opts) -> 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.push user_id if !opts.endpointName? @@ -37,4 +35,4 @@ module.exports = RateLimiterMiddlewear = logger.warn options, "rate limit exceeded" res.status(429) # Too many requests res.write("Rate limit reached, please try again later") - res.end() \ No newline at end of file + res.end() diff --git a/services/web/app/coffee/Features/Spelling/SpellingController.coffee b/services/web/app/coffee/Features/Spelling/SpellingController.coffee index 973655701b..cff53ec171 100644 --- a/services/web/app/coffee/Features/Spelling/SpellingController.coffee +++ b/services/web/app/coffee/Features/Spelling/SpellingController.coffee @@ -1,13 +1,15 @@ request = require 'request' Settings = require 'settings-sharelatex' logger = require 'logger-sharelatex' +AuthenticationController = require('../Authentication/AuthenticationController') TEN_SECONDS = 1000 * 10 module.exports = SpellingController = proxyRequestToSpellingApi: (req, res, next) -> + user_id = AuthenticationController.getLoggedInUserId(req) 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 request(url: Settings.apis.spelling.url + url, method: req.method, headers: req.headers, json: req.body, timeout:TEN_SECONDS) .on "error", (error) -> diff --git a/services/web/app/coffee/Features/StaticPages/HomeController.coffee b/services/web/app/coffee/Features/StaticPages/HomeController.coffee index 3e9ac8439c..3535c6c5eb 100755 --- a/services/web/app/coffee/Features/StaticPages/HomeController.coffee +++ b/services/web/app/coffee/Features/StaticPages/HomeController.coffee @@ -5,12 +5,13 @@ Path = require "path" fs = require "fs" ErrorController = require "../Errors/ErrorController" +AuthenticationController = require('../Authentication/AuthenticationController') homepageExists = fs.existsSync Path.resolve(__dirname + "/../../../views/external/home.jade") module.exports = HomeController = index : (req,res)-> - if req.session.user + if AuthenticationController.isUserLoggedIn(req)? if req.query.scribtex_path? res.redirect "/project?scribtex_path=#{req.query.scribtex_path}" else @@ -33,4 +34,4 @@ module.exports = HomeController = res.render "external/#{page}.jade", title: title else - ErrorController.notFound(req, res, next) \ No newline at end of file + ErrorController.notFound(req, res, next) diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee index 943c78f62d..09a9e82faf 100644 --- a/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee +++ b/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee @@ -13,7 +13,7 @@ module.exports = SubscriptionController = plansPage: (req, res, next) -> plans = SubscriptionViewModelBuilder.buildViewModel() - if !req.session.user? + if AuthenticationController.isUserLoggedIn(req)? baseUrl = "/register?redir=" else baseUrl = "" @@ -134,7 +134,7 @@ module.exports = SubscriptionController = successURL : "#{Settings.siteUrl}/user/subscription/billing-details/update" user : id : user._id - + updateBillingDetails: (req, res, next) -> res.redirect "/user/subscription?saved_billing_details=true" diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionGroupController.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionGroupController.coffee index 5b20608eea..c09ed1f47d 100644 --- a/services/web/app/coffee/Features/Subscription/SubscriptionGroupController.coffee +++ b/services/web/app/coffee/Features/Subscription/SubscriptionGroupController.coffee @@ -3,27 +3,28 @@ logger = require("logger-sharelatex") SubscriptionLocator = require("./SubscriptionLocator") ErrorsController = require("../Errors/ErrorController") SubscriptionDomainHandler = require("./SubscriptionDomainHandler") +AuthenticationController = require('../Authentication/AuthenticationController') _ = require("underscore") async = require("async") module.exports = addUserToGroup: (req, res)-> - adminUserId = req.session.user._id + adminUserId = AuthenticationController.getLoggedInUserId(req) newEmail = req.body?.email?.toLowerCase()?.trim() logger.log adminUserId:adminUserId, newEmail:newEmail, "adding user to group subscription" SubscriptionGroupHandler.addUserToGroup adminUserId, newEmail, (err, user)-> if err? logger.err err:err, newEmail:newEmail, adminUserId:adminUserId, "error adding user from group" return res.sendStatus 500 - result = + result = user:user if err and err.limitReached result.limitReached = true res.json(result) removeUserFromGroup: (req, res)-> - adminUserId = req.session.user._id + adminUserId = AuthenticationController.getLoggedInUserId(req) userToRemove_id = req.params.user_id logger.log adminUserId:adminUserId, userToRemove_id:userToRemove_id, "removing user from group subscription" 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" return res.sendStatus 500 res.send() - + removeSelfFromGroup: (req, res)-> 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" SubscriptionGroupHandler.removeUserFromGroup adminUserId, userToRemove_id, (err)-> if err? @@ -43,7 +44,7 @@ module.exports = res.send() renderSubscriptionGroupAdminPage: (req, res)-> - user_id = req.session.user._id + user_id = AuthenticationController.getLoggedInUserId(req) SubscriptionLocator.getUsersSubscription user_id, (err, subscription)-> if !subscription.groupPlan return res.redirect("/") @@ -55,11 +56,11 @@ module.exports = renderGroupInvitePage: (req, res)-> group_subscription_id = req.params.subscription_id - user_id = req.session.user._id + user_id = AuthenticationController.getLoggedInUserId(req) licence = SubscriptionDomainHandler.findDomainLicenceBySubscriptionId(group_subscription_id) if !licence? return ErrorsController.notFound(req, res) - jobs = + jobs = partOfGroup: (cb)-> SubscriptionGroupHandler.isUserPartOfGroup user_id, licence.group_subscription_id, cb subscription: (cb)-> @@ -77,15 +78,18 @@ module.exports = beginJoinGroup: (req, res)-> 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? - 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)-> subscription_id = req.params.subscription_id @@ -109,10 +113,10 @@ module.exports = return ErrorsController.notFound(req, res) res.render "subscriptions/group/successful_join", title: "Sucessfully joined group" - licenceName:licence.name + licenceName:licence.name exportGroupCsv: (req, res)-> - user_id = req.session.user._id + user_id = AuthenticationController.getLoggedInUserId(req) logger.log user_id: user_id, "exporting group csv" SubscriptionLocator.getUsersSubscription user_id, (err, subscription)-> if !subscription.groupPlan diff --git a/services/web/app/coffee/Features/Tags/TagsController.coffee b/services/web/app/coffee/Features/Tags/TagsController.coffee index 2e67be2fd4..0cd15ab5e7 100644 --- a/services/web/app/coffee/Features/Tags/TagsController.coffee +++ b/services/web/app/coffee/Features/Tags/TagsController.coffee @@ -1,48 +1,49 @@ TagsHandler = require("./TagsHandler") logger = require("logger-sharelatex") +AuthenticationController = require('../Authentication/AuthenticationController') module.exports = getAllTags: (req, res, next)-> - user_id = req.session.user._id + user_id = AuthenticationController.getLoggedInUserId(req) logger.log {user_id}, "getting tags" TagsHandler.getAllTags user_id, (error, allTags)-> return next(error) if error? res.json(allTags) - + createTag: (req, res, next) -> - user_id = req.session.user._id + user_id = AuthenticationController.getLoggedInUserId(req) name = req.body.name logger.log {user_id, name}, "creating tag" TagsHandler.createTag user_id, name, (error, tag) -> return next(error) if error? res.json(tag) - + addProjectToTag: (req, res, next) -> - user_id = req.session.user._id + user_id = AuthenticationController.getLoggedInUserId(req) {tag_id, project_id} = req.params logger.log {user_id, tag_id, project_id}, "adding tag to project" TagsHandler.addProjectToTag user_id, tag_id, project_id, (error) -> return next(error) if error? res.status(204).end() - + removeProjectFromTag: (req, res, next) -> - user_id = req.session.user._id + user_id = AuthenticationController.getLoggedInUserId(req) {tag_id, project_id} = req.params logger.log {user_id, tag_id, project_id}, "removing tag from project" TagsHandler.removeProjectFromTag user_id, tag_id, project_id, (error) -> return next(error) if error? res.status(204).end() - + deleteTag: (req, res, next) -> - user_id = req.session.user._id + user_id = AuthenticationController.getLoggedInUserId(req) tag_id = req.params.tag_id logger.log {user_id, tag_id}, "deleting tag" TagsHandler.deleteTag user_id, tag_id, (error) -> return next(error) if error? res.status(204).end() - + renameTag: (req, res, next) -> - user_id = req.session.user._id + user_id = AuthenticationController.getLoggedInUserId(req) tag_id = req.params.tag_id name = req.body?.name if !name? diff --git a/services/web/app/coffee/Features/TrackChanges/TrackChangesController.coffee b/services/web/app/coffee/Features/TrackChanges/TrackChangesController.coffee index f548cadde6..bc6e00a29a 100644 --- a/services/web/app/coffee/Features/TrackChanges/TrackChangesController.coffee +++ b/services/web/app/coffee/Features/TrackChanges/TrackChangesController.coffee @@ -5,17 +5,16 @@ AuthenticationController = require "../Authentication/AuthenticationController" module.exports = TrackChangesController = 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) \ No newline at end of file + 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) diff --git a/services/web/app/coffee/Features/Uploads/ProjectUploadController.coffee b/services/web/app/coffee/Features/Uploads/ProjectUploadController.coffee index 557a1d5449..de23c45015 100644 --- a/services/web/app/coffee/Features/Uploads/ProjectUploadController.coffee +++ b/services/web/app/coffee/Features/Uploads/ProjectUploadController.coffee @@ -4,11 +4,12 @@ fs = require "fs" Path = require "path" FileSystemImportManager = require "./FileSystemImportManager" ProjectUploadManager = require "./ProjectUploadManager" +AuthenticationController = require('../Authentication/AuthenticationController') module.exports = ProjectUploadController = uploadProject: (req, res, next) -> timer = new metrics.Timer("project-upload") - user_id = req.session.user._id + user_id = AuthenticationController.getLoggedInUserId(req) {originalname, path} = req.files.qqfile name = Path.basename(originalname, ".zip") ProjectUploadManager.createProjectFromZipArchive user_id, name, path, (error, project) -> @@ -24,7 +25,7 @@ module.exports = ProjectUploadController = project: project._id, file_path: path, file_name: name, "uploaded project" res.send success: true, project_id: project._id - + uploadFile: (req, res, next) -> timer = new metrics.Timer("file-upload") 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" return res.send success: false 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) -> fs.unlink path, -> timer.done() @@ -50,6 +51,3 @@ module.exports = ProjectUploadController = project_id: project_id, file_path: path, file_name: name, folder_id: folder_id "uploaded file" res.send success: true, entity_id: entity?._id - - - diff --git a/services/web/app/coffee/Features/User/UserController.coffee b/services/web/app/coffee/Features/User/UserController.coffee index 25eb2afd4c..ebbebd9c0a 100644 --- a/services/web/app/coffee/Features/User/UserController.coffee +++ b/services/web/app/coffee/Features/User/UserController.coffee @@ -8,6 +8,7 @@ logger = require("logger-sharelatex") metrics = require("../../infrastructure/Metrics") Url = require("url") AuthenticationManager = require("../Authentication/AuthenticationManager") +AuthenticationController = require('../Authentication/AuthenticationController') UserSessionsManager = require("./UserSessionsManager") UserUpdater = require("./UserUpdater") settings = require "settings-sharelatex" @@ -15,20 +16,21 @@ settings = require "settings-sharelatex" module.exports = UserController = deleteUser: (req, res)-> - user_id = req.session.user._id + user_id = AuthenticationController.getLoggedInUserId(req) UserDeleter.deleteUser user_id, (err)-> if !err? req.session?.destroy() res.sendStatus(200) 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, -> res.send() 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)-> if err? or !user? logger.err err:err, user_id:user_id, "problem updaing user settings" @@ -73,7 +75,7 @@ module.exports = UserController = if err? logger.err err:err, user_id:user_id, "error getting user for email update" 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 if err? logger.err err:err, "error populateGroupLicenceInvite" @@ -83,13 +85,13 @@ module.exports = UserController = metrics.inc "user.logout" logger.log user: req?.session?.user, "logging out" 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) ->)-> email = req.body.email @@ -106,10 +108,11 @@ module.exports = UserController = changePassword : (req, res, next = (error) ->)-> metrics.inc "user.password-change" 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? if(user) - logger.log user: req.session.user, "changing password" + logger.log user: user._id, "changing password" newPassword1 = req.body.newPassword1 newPassword2 = req.body.newPassword2 if newPassword1 != newPassword2 diff --git a/services/web/app/coffee/Features/User/UserPagesController.coffee b/services/web/app/coffee/Features/User/UserPagesController.coffee index 567cacd35c..c4bbb3de0a 100644 --- a/services/web/app/coffee/Features/User/UserPagesController.coffee +++ b/services/web/app/coffee/Features/User/UserPagesController.coffee @@ -4,6 +4,7 @@ ErrorController = require("../Errors/ErrorController") logger = require("logger-sharelatex") Settings = require("settings-sharelatex") fs = require('fs') +AuthenticationController = require('../Authentication/AuthenticationController') module.exports = @@ -22,14 +23,14 @@ module.exports = sharedProjectData: sharedProjectData newTemplateData: newTemplateData new_email:req.query.new_email || "" - + activateAccountPage: (req, res) -> # An 'activation' is actually just a password reset on an account that # was set with a random password originally. logger.log query:req.query, "activiate account page called" if !req.query?.user_id? or !req.query?.token? return ErrorController.notFound(req, res) - + UserGetter.getUser req.query.user_id, {email: 1, loginCount: 1}, (error, user) -> return next(error) if error? if !user @@ -53,8 +54,9 @@ module.exports = email: req.query.email 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? res.render 'user/settings', title:'account_settings' diff --git a/services/web/app/coffee/infrastructure/ExpressLocals.coffee b/services/web/app/coffee/infrastructure/ExpressLocals.coffee index d3b9d9a24b..dabe33af88 100644 --- a/services/web/app/coffee/infrastructure/ExpressLocals.coffee +++ b/services/web/app/coffee/infrastructure/ExpressLocals.coffee @@ -5,6 +5,7 @@ Settings = require('settings-sharelatex') SubscriptionFormatters = require('../Features/Subscription/SubscriptionFormatters') querystring = require('querystring') SystemMessageManager = require("../Features/SystemMessages/SystemMessageManager") +AuthenticationController = require("../Features/Authentication/AuthenticationController") _ = require("underscore") Modules = require "./Modules" Url = require "url" @@ -59,7 +60,7 @@ module.exports = (app, webRouter, apiRouter)-> res.locals.session = req.session next() - webRouter.use (req, res, next)-> + webRouter.use (req, res, next)-> cdnBlocked = req.query.nocdn == 'true' or req.session.cdnBlocked @@ -77,7 +78,7 @@ module.exports = (app, webRouter, apiRouter)-> staticFilesBase = Settings.cdn?.web?.darkHost else staticFilesBase = "" - + res.locals.jsPath = jsPath res.locals.fullJsPath = Url.resolve(staticFilesBase, jsPath) @@ -86,7 +87,7 @@ module.exports = (app, webRouter, apiRouter)-> path = Path.join(jsPath, jsFile) doFingerPrint = opts.fingerprint != false - + if !opts.qs? opts.qs = {} @@ -95,7 +96,7 @@ module.exports = (app, webRouter, apiRouter)-> if opts.cdn != false path = Url.resolve(staticFilesBase, path) - + qs = querystring.stringify(opts.qs) 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 next() @@ -143,7 +144,7 @@ module.exports = (app, webRouter, apiRouter)-> return formatedPrivileges[privilegeLevel] || "Private" next() - webRouter.use (req, res, next)-> + webRouter.use (req, res, next)-> res.locals.buildReferalUrl = (referal_medium) -> url = Settings.siteUrl if req.session? and req.session.user? and req.session.user.referal_id? @@ -167,7 +168,7 @@ module.exports = (app, webRouter, apiRouter)-> return "" res.locals.getLoggedInUserId = -> - return req.session.user?._id + return AuthenticationController.getLoggedInUserId(req) next() webRouter.use (req, res, next) -> @@ -179,11 +180,11 @@ module.exports = (app, webRouter, apiRouter)-> return req.query?[field] next() - webRouter.use (req, res, next)-> + webRouter.use (req, res, next)-> res.locals.fingerprint = getFingerprint next() - webRouter.use (req, res, next)-> + webRouter.use (req, res, next)-> res.locals.formatPrice = SubscriptionFormatters.formatPrice next() @@ -193,11 +194,11 @@ module.exports = (app, webRouter, apiRouter)-> next() webRouter.use (req, res, next)-> - if req.session.user? + if req.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 res.locals.justRegistered = true delete req.session.justRegistered @@ -223,7 +224,7 @@ module.exports = (app, webRouter, apiRouter)-> res.locals.nav[key] = _.clone(Settings.nav[key]) res.locals.templates = Settings.templateLinks next() - + webRouter.use (req, res, next) -> SystemMessageManager.getMessages (error, messages = []) -> res.locals.systemMessages = messages @@ -246,5 +247,3 @@ module.exports = (app, webRouter, apiRouter)-> res.locals.moduleIncludes = Modules.moduleIncludes res.locals.moduleIncludesAvailable = Modules.moduleIncludesAvailable next() - -