Use token in URL to force its precense when invite and allow easy dynamic notifications

This commit is contained in:
James Allen 2016-09-22 17:24:06 +01:00
parent d904e50041
commit e15976be21
7 changed files with 19 additions and 20 deletions

View file

@ -111,16 +111,15 @@ module.exports = CollaboratorsInviteController =
acceptInvite: (req, res, next) -> acceptInvite: (req, res, next) ->
projectId = req.params.Project_id projectId = req.params.Project_id
inviteId = req.params.invite_id token = req.params.token
{token} = req.body
currentUser = req.session.user currentUser = req.session.user
logger.log {projectId, inviteId, userId: currentUser._id}, "accepting invite" logger.log {projectId, userId: currentUser._id, token}, "got request to accept invite"
CollaboratorsInviteHandler.acceptInvite projectId, inviteId, token, currentUser, (err) -> CollaboratorsInviteHandler.acceptInvite projectId, token, currentUser, (err) ->
if err? if err?
logger.err {projectId, inviteId}, "error accepting invite by token" logger.err {projectId, token}, "error accepting invite by token"
return next(err) return next(err)
EditorRealTimeController.emitToRoom projectId, 'project:membership:changed', {invites: true, members: true} EditorRealTimeController.emitToRoom projectId, 'project:membership:changed', {invites: true, members: true}
AnalyticsManger.recordEvent(currentUser._id, "project-invite-accept", {inviteId:inviteId, projectId:projectId}) AnalyticsManger.recordEvent(currentUser._id, "project-invite-accept", {projectId:projectId, userId:currentUser._id})
if req.xhr if req.xhr
res.sendStatus 204 # Done async via project page notification res.sendStatus 204 # Done async via project page notification
else else

View file

@ -119,15 +119,15 @@ module.exports = CollaboratorsInviteHandler =
return callback(null, null) return callback(null, null)
callback(null, invite) callback(null, invite)
acceptInvite: (projectId, inviteId, tokenString, user, callback=(err)->) -> acceptInvite: (projectId, tokenString, user, callback=(err)->) ->
logger.log {projectId, inviteId, userId: user._id}, "accepting invite" logger.log {projectId, userId: user._id, tokenString}, "accepting invite"
CollaboratorsInviteHandler.getInviteByToken projectId, tokenString, (err, invite) -> CollaboratorsInviteHandler.getInviteByToken projectId, tokenString, (err, invite) ->
if err? if err?
logger.err {err, projectId, inviteId}, "error finding invite" logger.err {err, projectId, tokenString}, "error finding invite"
return callback(err) return callback(err)
if !invite if !invite
err = new Errors.NotFoundError("no matching invite found") err = new Errors.NotFoundError("no matching invite found")
logger.log {err, projectId, inviteId, tokenString}, "no matching invite found" logger.log {err, projectId, tokenString}, "no matching invite found"
return callback(err) return callback(err)
inviteId = invite._id inviteId = invite._id
CollaboratorsHandler.addUserIdToProject projectId, invite.sendingUserId, user._id, invite.privileges, (err) -> CollaboratorsHandler.addUserIdToProject projectId, invite.sendingUserId, user._id, invite.privileges, (err) ->

View file

@ -66,7 +66,7 @@ module.exports =
) )
webRouter.post( webRouter.post(
'/project/:Project_id/invite/:invite_id/accept', '/project/:Project_id/invite/token/:token/accept',
AuthenticationController.requireLogin(), AuthenticationController.requireLogin(),
CollaboratorsInviteController.acceptInvite CollaboratorsInviteController.acceptInvite
) )

View file

@ -20,7 +20,7 @@ block content
form.form( form.form(
name="acceptForm", name="acceptForm",
method="POST", method="POST",
action="/project/#{invite.projectId}/invite/#{invite._id}/accept" action="/project/#{invite.projectId}/invite/token/#{invite.token}/accept"
) )
input(name='_csrf', type='hidden', value=csrfToken) input(name='_csrf', type='hidden', value=csrfToken)
input(name='token', type='hidden', value="#{invite.token}") input(name='token', type='hidden', value="#{invite.token}")

View file

@ -24,7 +24,7 @@ define [
$scope.accept = () -> $scope.accept = () ->
$scope.notification.inflight = true $scope.notification.inflight = true
$http({ $http({
url: "/project/#{$scope.notification.messageOpts.projectId}/invite/#{$scope.notification.messageOpts.token}/accept" url: "/project/#{$scope.notification.messageOpts.projectId}/invite/token/#{$scope.notification.messageOpts.token}/accept"
method: "POST" method: "POST"
headers: headers:
"X-Csrf-Token": window.csrfToken "X-Csrf-Token": window.csrfToken

View file

@ -531,14 +531,12 @@ describe "CollaboratorsInviteController", ->
beforeEach -> beforeEach ->
@req.params = @req.params =
Project_id: @project_id Project_id: @project_id
invite_id: @invite_id = "thuseoautoh" token: @token = "mock-token"
@req.session = @req.session =
user: _id: @current_user_id = "current-user-id" user: _id: @current_user_id = "current-user-id"
@req.body =
token: "thsueothaueotauahsuet"
@res.render = sinon.stub() @res.render = sinon.stub()
@res.redirect = sinon.stub() @res.redirect = sinon.stub()
@CollaboratorsInviteHandler.acceptInvite = sinon.stub().callsArgWith(4, null) @CollaboratorsInviteHandler.acceptInvite = sinon.stub().callsArgWith(3, null)
@callback = sinon.stub() @callback = sinon.stub()
@next = sinon.stub() @next = sinon.stub()
@ -552,7 +550,9 @@ describe "CollaboratorsInviteController", ->
@res.redirect.calledWith("/project/#{@project_id}").should.equal true @res.redirect.calledWith("/project/#{@project_id}").should.equal true
it 'should have called acceptInvite', -> it 'should have called acceptInvite', ->
@CollaboratorsInviteHandler.acceptInvite.callCount.should.equal 1 @CollaboratorsInviteHandler.acceptInvite
.calledWith(@project_id, @token)
.should.equal true
it 'should have called emitToRoom', -> it 'should have called emitToRoom', ->
@EditorRealTimeController.emitToRoom.callCount.should.equal 1 @EditorRealTimeController.emitToRoom.callCount.should.equal 1
@ -562,7 +562,7 @@ describe "CollaboratorsInviteController", ->
beforeEach -> beforeEach ->
@err = new Error('woops') @err = new Error('woops')
@CollaboratorsInviteHandler.acceptInvite = sinon.stub().callsArgWith(4, @err) @CollaboratorsInviteHandler.acceptInvite = sinon.stub().callsArgWith(3, @err)
@CollaboratorsInviteController.acceptInvite @req, @res, @next @CollaboratorsInviteController.acceptInvite @req, @res, @next
it 'should not redirect to project page', -> it 'should not redirect to project page', ->

View file

@ -404,7 +404,7 @@ describe "CollaboratorsInviteHandler", ->
@CollaboratorsInviteHandler._tryCancelInviteNotification = sinon.stub().callsArgWith(1, null) @CollaboratorsInviteHandler._tryCancelInviteNotification = sinon.stub().callsArgWith(1, null)
@ProjectInvite.remove.callsArgWith(1, null) @ProjectInvite.remove.callsArgWith(1, null)
@call = (callback) => @call = (callback) =>
@CollaboratorsInviteHandler.acceptInvite @projectId, @inviteId, @token, @user, callback @CollaboratorsInviteHandler.acceptInvite @projectId, @token, @user, callback
afterEach -> afterEach ->
@_getInviteByToken.restore() @_getInviteByToken.restore()