From 62d544ccfc77827085f12188f2fc13eb81817507 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly Date: Wed, 27 Jul 2016 15:28:22 +0100 Subject: [PATCH] Redirect to project if user is already member. If invite is missing, and current user is already a member of the project, then just redirect to the project page --- .../CollaboratorsInviteController.coffee | 35 +++-- .../CollaboratorsInviteControllerTests.coffee | 128 +++++++++++------- 2 files changed, 103 insertions(+), 60 deletions(-) diff --git a/services/web/app/coffee/Features/Collaborators/CollaboratorsInviteController.coffee b/services/web/app/coffee/Features/Collaborators/CollaboratorsInviteController.coffee index aa886fdfff..5618da7db7 100644 --- a/services/web/app/coffee/Features/Collaborators/CollaboratorsInviteController.coffee +++ b/services/web/app/coffee/Features/Collaborators/CollaboratorsInviteController.coffee @@ -54,29 +54,40 @@ module.exports = CollaboratorsInviteController = projectId = req.params.Project_id token = req.params.token currentUser = req.session.user - CollaboratorsInviteHandler.getInviteByToken projectId, token, (err, invite) -> + _renderInvalidPage = () -> + res.render "project/invite/not-valid" + # get the target project + Project.findOne {_id: projectId}, {owner_ref: 1, name: 1, collaberator_refs: 1, readOnly_refs: 1}, (err, project) -> if err? - logger.err {projectId, token}, "error getting invite by token" + logger.err {err, projectId}, "error getting project" return next(err) - _renderInvalidPage = () -> - res.render "project/invite/not-valid" - if !invite - logger.log {projectId, token}, "no invite found for token" + if !project + logger.log {projectId}, "no project found" return _renderInvalidPage() - Project.findOne {_id: projectId}, {owner_ref: 1, name: 1}, (err, project) -> + # get the invite + CollaboratorsInviteHandler.getInviteByToken projectId, token, (err, invite) -> if err? - logger.err {err, projectId}, "error getting project" + logger.err {projectId, token}, "error getting invite by token" return next(err) - if !project - logger.log {projectId}, "no project found" - return _renderInvalidPage() - User.findOne {_id: project.owner_ref}, {email: 1, first_name: 1, last_name: 1}, (err, owner) -> + # check if invite is gone + if !invite + logger.log {projectId, token}, "no invite found for this token" + # check if user is already a member of the project, redirect to project if so + allMembers = (project.collaberator_refs || []).concat(project.readOnly_refs || []).map((oid) -> oid.toString()) + if currentUser._id in allMembers + logger.log {projectId, userId: currentUser._id}, "user is already a member of this project, redirecting" + return res.redirect "/project/#{projectId}" + else + return _renderInvalidPage() + # check the user who sent the invite exists + User.findOne {_id: invite.sendingUserId}, {email: 1, first_name: 1, last_name: 1}, (err, owner) -> if err? logger.err {err, projectId}, "error getting project owner" return next(err) if !owner logger.log {projectId}, "no project owner found" return _renderInvalidPage() + # finally render the invite res.render "project/invite/show", {invite, project, owner} acceptInvite: (req, res, next) -> diff --git a/services/web/test/UnitTests/coffee/Collaborators/CollaboratorsInviteControllerTests.coffee b/services/web/test/UnitTests/coffee/Collaborators/CollaboratorsInviteControllerTests.coffee index af10cb48de..3de79d9fad 100644 --- a/services/web/test/UnitTests/coffee/Collaborators/CollaboratorsInviteControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Collaborators/CollaboratorsInviteControllerTests.coffee @@ -173,6 +173,7 @@ describe "CollaboratorsInviteController", -> @req.session = user: _id: @current_user_id = "current-user-id" @res.render = sinon.stub() + @res.redirect = sinon.stub() @res.sendStatus = sinon.stub() @invite = { _id: ObjectId(), @@ -186,6 +187,8 @@ describe "CollaboratorsInviteController", -> _id: @project_id name: "some project" owner_ref: @invite.sendingUserId + collaberator_refs: [] + readOnly_refs: [] @owner = _id: @fakeProject.owner_ref first_name: "John" @@ -210,59 +213,17 @@ describe "CollaboratorsInviteController", -> it 'should not call next', -> @next.callCount.should.equal 0 - it 'should call getInviteByToken', -> - @CollaboratorsInviteHandler.getInviteByToken.callCount.should.equal 1 - it 'should call Project.findOne', -> @Project.findOne.callCount.should.equal 1 @Project.findOne.calledWith({_id: @project_id}).should.equal true + it 'should call getInviteByToken', -> + @CollaboratorsInviteHandler.getInviteByToken.callCount.should.equal 1 + it 'should call User.findOne', -> @User.findOne.callCount.should.equal 1 @User.findOne.calledWith({_id: @fakeProject.owner_ref}).should.equal true - describe 'when the getInviteByToken produces an error', -> - - beforeEach -> - @err = new Error('woops') - @CollaboratorsInviteHandler.getInviteByToken.callsArgWith(2, @err) - @CollaboratorsInviteController.viewInvite @req, @res, @next - - it 'should call next with the error', -> - @next.callCount.should.equal 1 - @next.calledWith(@err).should.equal true - - it 'should call getInviteByToken', -> - @CollaboratorsInviteHandler.getInviteByToken.callCount.should.equal 1 - - it 'should not call Project.findOne', -> - @Project.findOne.callCount.should.equal 0 - - it 'should not call User.findOne', -> - @User.findOne.callCount.should.equal 0 - - describe 'when the getInviteByToken does not produce an invite', -> - - beforeEach -> - @CollaboratorsInviteHandler.getInviteByToken.callsArgWith(2, null, null) - @CollaboratorsInviteController.viewInvite @req, @res, @next - - it 'should render the not-valid view template', -> - @res.render.callCount.should.equal 1 - @res.render.calledWith('project/invite/not-valid').should.equal true - - it 'should not call next', -> - @next.callCount.should.equal 0 - - it 'should call getInviteByToken', -> - @CollaboratorsInviteHandler.getInviteByToken.callCount.should.equal 1 - - it 'should not call Project.findOne', -> - @Project.findOne.callCount.should.equal 0 - - it 'should not call User.findOne', -> - @User.findOne.callCount.should.equal 0 - describe 'when Project.findOne produces an error', -> beforeEach -> @@ -273,13 +234,13 @@ describe "CollaboratorsInviteController", -> @next.callCount.should.equal 1 expect(@next.firstCall.args[0]).to.be.instanceof Error - it 'should call getInviteByToken', -> - @CollaboratorsInviteHandler.getInviteByToken.callCount.should.equal 1 - it 'should call Project.findOne', -> @Project.findOne.callCount.should.equal 1 @Project.findOne.calledWith({_id: @project_id}).should.equal true + it 'should not call getInviteByToken', -> + @CollaboratorsInviteHandler.getInviteByToken.callCount.should.equal 0 + it 'should not call User.findOne', -> @User.findOne.callCount.should.equal 0 @@ -300,9 +261,80 @@ describe "CollaboratorsInviteController", -> @Project.findOne.callCount.should.equal 1 @Project.findOne.calledWith({_id: @project_id}).should.equal true + it 'should not call getInviteByToken', -> + @CollaboratorsInviteHandler.getInviteByToken.callCount.should.equal 0 + it 'should not call User.findOne', -> @User.findOne.callCount.should.equal 0 + describe 'when the getInviteByToken produces an error', -> + + beforeEach -> + @err = new Error('woops') + @CollaboratorsInviteHandler.getInviteByToken.callsArgWith(2, @err) + @CollaboratorsInviteController.viewInvite @req, @res, @next + + it 'should call next with the error', -> + @next.callCount.should.equal 1 + @next.calledWith(@err).should.equal true + + it 'should call Project.findOne', -> + @Project.findOne.callCount.should.equal 1 + + it 'should call getInviteByToken', -> + @CollaboratorsInviteHandler.getInviteByToken.callCount.should.equal 1 + + it 'should not call User.findOne', -> + @User.findOne.callCount.should.equal 0 + + describe 'when the getInviteByToken does not produce an invite', -> + + describe 'when the user is not already a member of this project', -> + + beforeEach -> + @CollaboratorsInviteHandler.getInviteByToken.callsArgWith(2, null, null) + @CollaboratorsInviteController.viewInvite @req, @res, @next + + it 'should render the not-valid view template', -> + @res.render.callCount.should.equal 1 + @res.render.calledWith('project/invite/not-valid').should.equal true + + it 'should not call next', -> + @next.callCount.should.equal 0 + + it 'should call Project.findOne', -> + @Project.findOne.callCount.should.equal 1 + + it 'should call getInviteByToken', -> + @CollaboratorsInviteHandler.getInviteByToken.callCount.should.equal 1 + + it 'should not call User.findOne', -> + @User.findOne.callCount.should.equal 0 + + describe 'when the user is already a member of the project', -> + + beforeEach -> + @fakeProject.collaberator_refs = [ObjectId(), @current_user_id, ObjectId()] + @Project.findOne.callsArgWith(2, null, @fakeProject) + @CollaboratorsInviteHandler.getInviteByToken.callsArgWith(2, null, null) + @CollaboratorsInviteController.viewInvite @req, @res, @next + + it 'should redirect to the project page', -> + @res.redirect.callCount.should.equal 1 + @res.redirect.calledWith("/project/#{@project_id}").should.equal true + + it 'should not call next', -> + @next.callCount.should.equal 0 + + it 'should call Project.findOne', -> + @Project.findOne.callCount.should.equal 1 + + it 'should call getInviteByToken', -> + @CollaboratorsInviteHandler.getInviteByToken.callCount.should.equal 1 + + it 'should not call User.findOne', -> + @User.findOne.callCount.should.equal 0 + describe 'when User.findOne produces an error', -> beforeEach ->