mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Use token in URL to force its precense when invite and allow easy dynamic notifications
This commit is contained in:
parent
d904e50041
commit
e15976be21
7 changed files with 19 additions and 20 deletions
|
@ -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
|
||||||
|
|
|
@ -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) ->
|
||||||
|
|
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
|
@ -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}")
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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', ->
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in a new issue