Skip to content

Commit

Permalink
[firebase-analytics] Fix numeric chars not allow in event names (#8516)
Browse files Browse the repository at this point in the history
The eventName and userPropertyName for a firebase event support alphanumeric values but the regex was not allowing numeric characters.

Updates regex and adds additional check to ensure the first char is alphabetic.
  • Loading branch information
thorbenprimke committed May 29, 2020
1 parent ae90e59 commit a5bec1f
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 41 deletions.
2 changes: 2 additions & 0 deletions packages/expo-firebase-analytics/CHANGELOG.md
Expand Up @@ -8,6 +8,8 @@

### 🐛 Bug fixes

- Fixes `parseEvent` and `parseUserProperty` to allow numeric characters in the name parameter. ([#8516](https://github.com/expo/expo/pull/8516) by [@thorbenprimke](https://github.com/thorbenprimke))

## 2.4.0 — 2020-05-27

### 🎉 New features
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 13 additions & 18 deletions packages/expo-firebase-analytics/build/FirebaseAnalyticsJS.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/expo-firebase-analytics/package.json
Expand Up @@ -32,6 +32,9 @@
"author": "650 Industries, Inc.",
"license": "MIT",
"homepage": "https://github.com/expo/expo/tree/master/packages/expo-firebase-analytics",
"jest": {
"preset": "expo-module-scripts"
},
"unimodulePeerDependencies": {
"@unimodules/core": "*",
"expo-constants": "*"
Expand Down
38 changes: 16 additions & 22 deletions packages/expo-firebase-analytics/src/FirebaseAnalyticsJS.ts
Expand Up @@ -172,6 +172,18 @@ class FirebaseAnalyticsJS {
}
}

private static isValidName(name: string, maxLength: number): boolean {
return !!(
name &&
name.length &&
name.length <= maxLength &&
name.match(/^[A-Za-z][A-Za-z_\d]*$/) &&
!name.startsWith('firebase_') &&
!name.startsWith('google_') &&
!name.startsWith('ga_')
);
}

/**
* Parses an event (as passed to logEvent) and throws an error when the
* event-name or parameters are invalid.
Expand All @@ -184,18 +196,9 @@ class FirebaseAnalyticsJS {
eventName: string,
eventParams?: { [key: string]: any }
): FirebaseAnalyticsJSCodedEvent {
if (
!eventName ||
!eventName.length ||
eventName.length > 40 ||
eventName[0] === '_' ||
!eventName.match(/^[A-Za-z_]+$/) ||
eventName.startsWith('firebase_') ||
eventName.startsWith('google_') ||
eventName.startsWith('ga_')
) {
if (!FirebaseAnalyticsJS.isValidName(eventName, 40)) {
throw new Error(
'Invalid event-name specified. Should contain 1 to 40 alphanumeric characters or underscores. The name must start with an alphabetic character.'
`Invalid event-name (${eventName}) specified. Should contain 1 to 40 alphanumeric characters or underscores. The name must start with an alphabetic character.`
);
}
const params: FirebaseAnalyticsJSCodedEvent = {
Expand Down Expand Up @@ -226,18 +229,9 @@ class FirebaseAnalyticsJS {
userPropertyName: string,
userPropertyValue: any
): string {
if (
!userPropertyName.length ||
userPropertyName.length > 24 ||
userPropertyName[0] === '_' ||
!userPropertyName.match(/^[A-Za-z_]+$/) ||
userPropertyName === 'user_id' ||
userPropertyName.startsWith('firebase_') ||
userPropertyName.startsWith('google_') ||
userPropertyName.startsWith('ga_')
) {
if (!FirebaseAnalyticsJS.isValidName(userPropertyName, 24) || userPropertyName === 'user_id') {
throw new Error(
'Invalid user-property name specified. Should contain 1 to 24 alphanumeric characters or underscores. The name must start with an alphabetic character.'
`Invalid user-property name (${userPropertyName}) specified. Should contain 1 to 24 alphanumeric characters or underscores. The name must start with an alphabetic character.`
);
}
if (
Expand Down
@@ -0,0 +1,78 @@
import FirebaseAnalyticsJS from '../FirebaseAnalyticsJS';

let eventName = '';
const expectedErrorMessage = (name, eventName, maxLength) =>
`Invalid ${name} (${eventName}) specified. Should contain 1 to ${maxLength} alphanumeric characters or underscores. The name must start with an alphabetic character.`;
const options = {
clientId: '0',
sessionId: '0',
};

it(`Verfies parseEvent eventName validation`, async () => {
const name = 'event-name';
expect.assertions(3);
FirebaseAnalyticsJS.parseEvent(options, 'MyAnalyticsEvent');

try {
eventName = '_MyAnalyticsEvent';
FirebaseAnalyticsJS.parseEvent(options, eventName);
} catch (error) {
expect(error.message).toBe(expectedErrorMessage(name, eventName, 40));
}

try {
eventName = '0MyAnalyticsEvent';
FirebaseAnalyticsJS.parseEvent(options, eventName);
} catch (error) {
expect(error.message).toBe(expectedErrorMessage(name, eventName, 40));
}

FirebaseAnalyticsJS.parseEvent(options, 'MyAnalyticsEvent0');

try {
eventName = '0SuperLongNameThatIsMoreThan40CharactersInLength';
FirebaseAnalyticsJS.parseEvent(options, eventName);
} catch (error) {
expect(error.message).toBe(expectedErrorMessage(name, eventName, 40));
}

FirebaseAnalyticsJS.parseEvent(options, 'user_id');
});

it(`Verfies parseUserProperty userPropertyName validation`, async () => {
const name = 'user-property name';
expect.assertions(4);
const value = 'value';

FirebaseAnalyticsJS.parseUserProperty(options, 'MyAnalyticsEvent', value);

try {
eventName = '_MyAnalyticsEvent';
FirebaseAnalyticsJS.parseUserProperty(options, eventName, value);
} catch (error) {
expect(error.message).toBe(expectedErrorMessage(name, eventName, 24));
}

try {
eventName = '0MyAnalyticsEvent';
FirebaseAnalyticsJS.parseUserProperty(options, eventName, value);
} catch (error) {
expect(error.message).toBe(expectedErrorMessage(name, eventName, 24));
}

FirebaseAnalyticsJS.parseUserProperty(options, 'MyAnalyticsEvent0', value);

try {
eventName = '0LongNameThatIsMoreThan24ButLessThan40';
FirebaseAnalyticsJS.parseUserProperty(options, eventName, value);
} catch (error) {
expect(error.message).toBe(expectedErrorMessage(name, eventName, 24));
}

try {
eventName = 'user_id';
FirebaseAnalyticsJS.parseUserProperty(options, eventName, value);
} catch (error) {
expect(error.message).toBe(expectedErrorMessage(name, eventName, 24));
}
});

0 comments on commit a5bec1f

Please sign in to comment.