Merge pull request #8620 from overleaf/ta-analytics-attributes-validate

Ignore Invalid Analytics Attributes

GitOrigin-RevId: 6e3ffc1dcc6088966480ad0704a988174e4fd3fb
This commit is contained in:
Timothée Alby 2022-07-07 10:00:36 +02:00 committed by Copybot
parent 22e24b1763
commit 8f41431719
2 changed files with 72 additions and 0 deletions

View file

@ -131,6 +131,9 @@ function updateEditingSession(userId, projectId, countryCode, segmentation) {
if (_isAnalyticsDisabled() || _isSmokeTestUser(userId)) { if (_isAnalyticsDisabled() || _isSmokeTestUser(userId)) {
return return
} }
if (!_isSegmentationValid(segmentation)) {
return
}
Metrics.analyticsQueue.inc({ Metrics.analyticsQueue.inc({
status: 'adding', status: 'adding',
event_type: 'editing-session', event_type: 'editing-session',
@ -161,6 +164,12 @@ function _recordEvent(
{ analyticsId, userId, event, segmentation, isLoggedIn }, { analyticsId, userId, event, segmentation, isLoggedIn },
{ delay } = {} { delay } = {}
) { ) {
if (!_isAttributeValid(event)) {
return
}
if (!_isSegmentationValid(segmentation)) {
return
}
Metrics.analyticsQueue.inc({ status: 'adding', event_type: 'event' }) Metrics.analyticsQueue.inc({ status: 'adding', event_type: 'event' })
analyticsEventsQueue analyticsEventsQueue
.add( .add(
@ -184,6 +193,9 @@ function _recordEvent(
} }
function _setUserProperty({ analyticsId, propertyName, propertyValue }) { function _setUserProperty({ analyticsId, propertyName, propertyValue }) {
if (!_isAttributeValid(propertyName) || !_isAttributeValid(propertyValue)) {
return
}
Metrics.analyticsQueue.inc({ Metrics.analyticsQueue.inc({
status: 'adding', status: 'adding',
event_type: 'user-property', event_type: 'user-property',
@ -230,6 +242,21 @@ function _checkPropertyValue(propertyValue) {
} }
} }
function _isAttributeValid(attribute) {
return attribute && /^[a-zA-Z0-9-_.:;,/]+$/.test(attribute)
}
function _isSegmentationValid(segmentation) {
if (!segmentation) {
return true
}
const hasAnyInvalidAttribute = [
...Object.keys(segmentation),
...Object.values(segmentation),
].some(attribute => !_isAttributeValid(attribute))
return !hasAnyInvalidAttribute
}
function getIdsFromSession(session) { function getIdsFromSession(session) {
const analyticsId = _.get(session, ['analyticsId']) const analyticsId = _.get(session, ['analyticsId'])
const userId = SessionManager.getLoggedInUserId(session) const userId = SessionManager.getLoggedInUserId(session)

View file

@ -106,6 +106,51 @@ describe('AnalyticsManager', function () {
) )
sinon.assert.notCalled(this.Queues.createScheduledJob) sinon.assert.notCalled(this.Queues.createScheduledJob)
}) })
it('editing session segmentation is not valid', function () {
this.AnalyticsManager.updateEditingSession(
this.fakeUserId,
'789ghi',
'fr',
{ key: '<alert>' }
)
sinon.assert.notCalled(this.analyticsEditingSessionQueue.add)
})
it('event is not valid', async function () {
await this.AnalyticsManager.recordEventForUser(
this.fakeUserId,
'not an event!'
)
sinon.assert.notCalled(this.analyticsEventsQueue.add)
})
it('event segmentation is not valid', async function () {
await this.AnalyticsManager.recordEventForUser(
this.fakeUserId,
'an_event',
{ not_a: 'Valid Segmentation!' }
)
sinon.assert.notCalled(this.analyticsEventsQueue.add)
})
it('user property name is not valid', async function () {
await this.AnalyticsManager.setUserPropertyForUser(
this.fakeUserId,
'an invalid property',
'a_value'
)
sinon.assert.notCalled(this.analyticsUserPropertiesQueue.add)
})
it('user property value is not valid', async function () {
await this.AnalyticsManager.setUserPropertyForUser(
this.fakeUserId,
'a_property',
'an invalid value'
)
sinon.assert.notCalled(this.analyticsUserPropertiesQueue.add)
})
}) })
describe('queues the appropriate message for', function () { describe('queues the appropriate message for', function () {