Merge pull request #4655 from overleaf/jel-gallery-event

Fix onclick event propagation

GitOrigin-RevId: bfcc3840e1768ed0f91e5fefbaee1738e36f6752
This commit is contained in:
June Kelly 2021-08-11 09:50:38 +01:00 committed by Copybot
parent 0acd81dfc0
commit 8b9d202518
4 changed files with 40 additions and 24 deletions

View file

@ -32,6 +32,7 @@ module.exports = {
}
const userId =
SessionManager.getLoggedInUserId(req.session) || req.sessionID
delete req.body._csrf
AnalyticsManager.recordEvent(userId, req.params.event, req.body)
res.sendStatus(202)
},

View file

@ -1,4 +1,3 @@
import { postJSON } from './fetch-json'
import sessionStorage from '../infrastructure/session-storage'
const CACHE_KEY = 'mbEvents'
@ -10,11 +9,7 @@ export function send(category, action, label, value) {
}
export function sendMB(key, segmentation = {}) {
postJSON(`/event/${key}`, { body: segmentation, keepalive: true }).catch(
() => {
// ignore errors
}
)
sendBeacon(key, segmentation)
}
export function sendMBOnce(key, segmentation = {}) {
@ -39,3 +34,13 @@ export function sendMBSampled(key, body = {}, rate = 0.01) {
sendMB(key, body)
}
}
function sendBeacon(key, data) {
if (!navigator || !navigator.sendBeacon) return
data._csrf = window.csrfToken
const blob = new Blob([JSON.stringify(data)], {
type: 'application/json; charset=UTF-8',
})
navigator.sendBeacon(`/event/${key}`, blob)
}

View file

@ -15,6 +15,7 @@
import moment from 'moment'
import App from '../base'
import '../modules/localStorage'
import { sendMB } from '../infrastructure/event-tracking'
const CACHE_KEY = 'mbEvents'
// keep track of how many heartbeats we've sent so we can calculate how
@ -89,21 +90,7 @@ App.factory('eventTracking', function ($http, localStorage) {
return (nextHeartbeat = moment().add(backoffSecs, 'seconds').toDate())
},
sendMB(key, segmentation) {
if (segmentation == null) {
segmentation = {}
}
fetch(`/event/${key}`, {
method: 'POST',
body: JSON.stringify(segmentation),
keepalive: true,
headers: {
'X-CSRF-Token': window.csrfToken,
'Content-Type': 'application/json',
Accept: 'application/json',
},
})
},
sendMB,
sendMBSampled(key, segmentation, rate = 0.01) {
if (Math.random() < rate) {

View file

@ -61,21 +61,28 @@ describe('AnalyticsController', function () {
describe('recordEvent', function () {
beforeEach(function () {
const body = {
foo: 'stuff',
_csrf: 'atoken123',
}
this.req = {
params: {
event: 'i_did_something',
},
body: 'stuff',
body,
sessionID: 'sessionIDHere',
session: {},
}
this.expectedData = Object.assign({}, body)
delete this.expectedData._csrf
})
it('should use the user_id', function (done) {
this.SessionManager.getLoggedInUserId.returns('1234')
this.controller.recordEvent(this.req, this.res)
this.AnalyticsManager.recordEvent
.calledWith('1234', this.req.params.event, this.req.body)
.calledWith('1234', this.req.params.event, this.expectedData)
.should.equal(true)
done()
})
@ -83,7 +90,23 @@ describe('AnalyticsController', function () {
it('should use the session id', function (done) {
this.controller.recordEvent(this.req, this.res)
this.AnalyticsManager.recordEvent
.calledWith(this.req.sessionID, this.req.params.event, this.req.body)
.calledWith(
this.req.sessionID,
this.req.params.event,
this.expectedData
)
.should.equal(true)
done()
})
it('should remove the CSRF token before sending to the manager', function (done) {
this.controller.recordEvent(this.req, this.res)
this.AnalyticsManager.recordEvent
.calledWith(
this.req.sessionID,
this.req.params.event,
this.expectedData
)
.should.equal(true)
done()
})