Просмотр исходного кода

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
Shane Kilkelly 10 лет назад
Родитель
Сommit
62d544ccfc

+ 23 - 12
services/web/app/coffee/Features/Collaborators/CollaboratorsInviteController.coffee

@@ -54,29 +54,40 @@ module.exports = CollaboratorsInviteController =
 		projectId = req.params.Project_id
 		projectId = req.params.Project_id
 		token = req.params.token
 		token = req.params.token
 		currentUser = req.session.user
 		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?
 			if err?
-				logger.err {projectId, token}, "error getting invite by token"
+				logger.err {err, projectId}, "error getting project"
 				return next(err)
 				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()
 				return _renderInvalidPage()
-			Project.findOne {_id: projectId}, {owner_ref: 1, name: 1}, (err, project) ->
+			# get the invite
+			CollaboratorsInviteHandler.getInviteByToken projectId, token, (err, invite) ->
 				if err?
 				if err?
-					logger.err {err, projectId}, "error getting project"
+					logger.err {projectId, token}, "error getting invite by token"
 					return next(err)
 					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?
 					if err?
 						logger.err {err, projectId}, "error getting project owner"
 						logger.err {err, projectId}, "error getting project owner"
 						return next(err)
 						return next(err)
 					if !owner
 					if !owner
 						logger.log {projectId}, "no project owner found"
 						logger.log {projectId}, "no project owner found"
 						return _renderInvalidPage()
 						return _renderInvalidPage()
+					# finally render the invite
 					res.render "project/invite/show", {invite, project, owner}
 					res.render "project/invite/show", {invite, project, owner}
 
 
 	acceptInvite: (req, res, next) ->
 	acceptInvite: (req, res, next) ->

+ 72 - 40
services/web/test/UnitTests/coffee/Collaborators/CollaboratorsInviteControllerTests.coffee

@@ -173,6 +173,7 @@ describe "CollaboratorsInviteController", ->
 			@req.session =
 			@req.session =
 				user: _id: @current_user_id = "current-user-id"
 				user: _id: @current_user_id = "current-user-id"
 			@res.render = sinon.stub()
 			@res.render = sinon.stub()
+			@res.redirect = sinon.stub()
 			@res.sendStatus = sinon.stub()
 			@res.sendStatus = sinon.stub()
 			@invite = {
 			@invite = {
 				_id: ObjectId(),
 				_id: ObjectId(),
@@ -186,6 +187,8 @@ describe "CollaboratorsInviteController", ->
 				_id: @project_id
 				_id: @project_id
 				name: "some project"
 				name: "some project"
 				owner_ref: @invite.sendingUserId
 				owner_ref: @invite.sendingUserId
+				collaberator_refs: []
+				readOnly_refs: []
 			@owner =
 			@owner =
 				_id: @fakeProject.owner_ref
 				_id: @fakeProject.owner_ref
 				first_name: "John"
 				first_name: "John"
@@ -210,41 +213,41 @@ describe "CollaboratorsInviteController", ->
 			it 'should not call next', ->
 			it 'should not call next', ->
 				@next.callCount.should.equal 0
 				@next.callCount.should.equal 0
 
 
-			it 'should call getInviteByToken', ->
-				@CollaboratorsInviteHandler.getInviteByToken.callCount.should.equal 1
-
 			it 'should call Project.findOne', ->
 			it 'should call Project.findOne', ->
 				@Project.findOne.callCount.should.equal 1
 				@Project.findOne.callCount.should.equal 1
 				@Project.findOne.calledWith({_id: @project_id}).should.equal true
 				@Project.findOne.calledWith({_id: @project_id}).should.equal true
 
 
+			it 'should call getInviteByToken', ->
+				@CollaboratorsInviteHandler.getInviteByToken.callCount.should.equal 1
+
 			it 'should call User.findOne', ->
 			it 'should call User.findOne', ->
 				@User.findOne.callCount.should.equal 1
 				@User.findOne.callCount.should.equal 1
 				@User.findOne.calledWith({_id: @fakeProject.owner_ref}).should.equal true
 				@User.findOne.calledWith({_id: @fakeProject.owner_ref}).should.equal true
 
 
-		describe 'when the getInviteByToken produces an error', ->
+		describe 'when Project.findOne produces an error', ->
 
 
 			beforeEach ->
 			beforeEach ->
-				@err = new Error('woops')
-				@CollaboratorsInviteHandler.getInviteByToken.callsArgWith(2, @err)
+				@Project.findOne.callsArgWith(2, new Error('woops'))
 				@CollaboratorsInviteController.viewInvite @req, @res, @next
 				@CollaboratorsInviteController.viewInvite @req, @res, @next
 
 
-			it 'should call next with the error', ->
+			it 'should produce an error', ->
 				@next.callCount.should.equal 1
 				@next.callCount.should.equal 1
-				@next.calledWith(@err).should.equal true
+				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 Project.findOne', ->
-				@Project.findOne.callCount.should.equal 0
+			it 'should not call getInviteByToken', ->
+				@CollaboratorsInviteHandler.getInviteByToken.callCount.should.equal 0
 
 
 			it 'should not call User.findOne', ->
 			it 'should not call User.findOne', ->
 				@User.findOne.callCount.should.equal 0
 				@User.findOne.callCount.should.equal 0
 
 
-		describe 'when the getInviteByToken does not produce an invite', ->
+		describe 'when Project.findOne does not find a project', ->
 
 
 			beforeEach ->
 			beforeEach ->
-				@CollaboratorsInviteHandler.getInviteByToken.callsArgWith(2, null, null)
+				@Project.findOne.callsArgWith(2, null, null)
 				@CollaboratorsInviteController.viewInvite @req, @res, @next
 				@CollaboratorsInviteController.viewInvite @req, @res, @next
 
 
 			it 'should render the not-valid view template', ->
 			it 'should render the not-valid view template', ->
@@ -254,54 +257,83 @@ describe "CollaboratorsInviteController", ->
 			it 'should not call next', ->
 			it 'should not call next', ->
 				@next.callCount.should.equal 0
 				@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 not call Project.findOne', ->
-				@Project.findOne.callCount.should.equal 0
+			it 'should not call getInviteByToken', ->
+				@CollaboratorsInviteHandler.getInviteByToken.callCount.should.equal 0
 
 
 			it 'should not call User.findOne', ->
 			it 'should not call User.findOne', ->
 				@User.findOne.callCount.should.equal 0
 				@User.findOne.callCount.should.equal 0
 
 
-		describe 'when Project.findOne produces an error', ->
+		describe 'when the getInviteByToken produces an error', ->
 
 
 			beforeEach ->
 			beforeEach ->
-				@Project.findOne.callsArgWith(2, new Error('woops'))
+				@err = new Error('woops')
+				@CollaboratorsInviteHandler.getInviteByToken.callsArgWith(2, @err)
 				@CollaboratorsInviteController.viewInvite @req, @res, @next
 				@CollaboratorsInviteController.viewInvite @req, @res, @next
 
 
-			it 'should produce an error', ->
+			it 'should call next with the error', ->
 				@next.callCount.should.equal 1
 				@next.callCount.should.equal 1
-				expect(@next.firstCall.args[0]).to.be.instanceof Error
-
-			it 'should call getInviteByToken', ->
-				@CollaboratorsInviteHandler.getInviteByToken.callCount.should.equal 1
+				@next.calledWith(@err).should.equal true
 
 
 			it 'should call Project.findOne', ->
 			it 'should call Project.findOne', ->
 				@Project.findOne.callCount.should.equal 1
 				@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 not call User.findOne', ->
 			it 'should not call User.findOne', ->
 				@User.findOne.callCount.should.equal 0
 				@User.findOne.callCount.should.equal 0
 
 
-		describe 'when Project.findOne does not find a project', ->
+		describe 'when the getInviteByToken does not produce an invite', ->
 
 
-			beforeEach ->
-				@Project.findOne.callsArgWith(2, null, null)
-				@CollaboratorsInviteController.viewInvite @req, @res, @next
+			describe 'when the user is not already a member of this project', ->
 
 
-			it 'should render the not-valid view template', ->
-				@res.render.callCount.should.equal 1
-				@res.render.calledWith('project/invite/not-valid').should.equal true
+				beforeEach ->
+					@CollaboratorsInviteHandler.getInviteByToken.callsArgWith(2, null, null)
+					@CollaboratorsInviteController.viewInvite @req, @res, @next
 
 
-			it 'should not call next', ->
-				@next.callCount.should.equal 0
+				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 call Project.findOne', ->
-				@Project.findOne.callCount.should.equal 1
-				@Project.findOne.calledWith({_id: @project_id}).should.equal true
+				it 'should not call next', ->
+					@next.callCount.should.equal 0
 
 
-			it 'should not call User.findOne', ->
-				@User.findOne.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', ->
 		describe 'when User.findOne produces an error', ->