Selaa lähdekoodia

Loose regex filter for analytics events (#10329)

Allows `Date` objects being sent as attribute values
and spaces in event segmentation values

GitOrigin-RevId: ce3bf5023941a011ba612e9a3a17b92f76f9860b
Miguel Serrano 3 vuotta sitten
vanhempi
sitoutus
900c5b29cb

+ 23 - 6
services/web/app/src/Features/Analytics/AnalyticsManager.js

@@ -193,7 +193,10 @@ function _recordEvent(
 }
 
 function _setUserProperty({ analyticsId, propertyName, propertyValue }) {
-  if (!_isAttributeValid(propertyName) || !_isAttributeValid(propertyValue)) {
+  if (
+    !_isAttributeValid(propertyName) ||
+    !_isAttributeValueValid(propertyValue)
+  ) {
     return
   }
   Metrics.analyticsQueue.inc({
@@ -246,15 +249,29 @@ function _isAttributeValid(attribute) {
   return !attribute || /^[a-zA-Z0-9-_.:;,/]+$/.test(attribute)
 }
 
+function _isAttributeValueValid(attributeValue) {
+  return _isAttributeValid(attributeValue) || attributeValue instanceof Date
+}
+
+function _isSegmentationValueValid(attributeValue) {
+  // spaces are allowed for segmentation values
+  return !attributeValue || /^[a-zA-Z0-9-_.:;,/ ]+$/.test(attributeValue)
+}
+
 function _isSegmentationValid(segmentation) {
   if (!segmentation) {
     return true
   }
-  const hasAnyInvalidAttribute = [
-    ...Object.keys(segmentation),
-    ...Object.values(segmentation),
-  ].some(attribute => !_isAttributeValid(attribute))
-  return !hasAnyInvalidAttribute
+
+  const hasAnyInvalidKey = [...Object.keys(segmentation)].some(
+    key => !_isAttributeValid(key)
+  )
+
+  const hasAnyInvalidValue = [...Object.values(segmentation)].some(
+    value => !_isSegmentationValueValid(value)
+  )
+
+  return !hasAnyInvalidKey && !hasAnyInvalidValue
 }
 
 function getIdsFromSession(session) {

+ 14 - 0
services/web/test/unit/src/Analytics/AnalyticsManagerTests.js

@@ -225,6 +225,20 @@ describe('AnalyticsManager', function () {
       })
     })
 
+    it('empty space in event segmentation value', async function () {
+      await this.AnalyticsManager.recordEventForUser(
+        this.fakeUserId,
+        'an_event',
+        { segment: 'a value with spaces' }
+      )
+      sinon.assert.calledWithMatch(this.analyticsEventsQueue.add, 'event', {
+        analyticsId: this.analyticsId,
+        event: 'an_event',
+        segmentation: { segment: 'a value with spaces' },
+        isLoggedIn: true,
+      })
+    })
+
     it('boolean field in event segmentation', async function () {
       await this.AnalyticsManager.recordEventForUser(
         this.fakeUserId,