Skip to content

Commit

Permalink
refactor: Move generateHash methods into utility class (#531)
Browse files Browse the repository at this point in the history
  • Loading branch information
rmi22186 authored and alexs-mparticle committed May 15, 2023
1 parent 2d3d575 commit 029f51e
Show file tree
Hide file tree
Showing 10 changed files with 528 additions and 40 deletions.
2 changes: 2 additions & 0 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@
},
"dependencies": {
"@babel/runtime": "^7.6.0",
"jest-environment-jsdom": "^29.5.0",
"slugify": "^1.3.6"
}
}
16 changes: 11 additions & 5 deletions src/configAPIClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ export interface IKitConfigs {
eventNameFilters: number[];
eventTypeFilters: number[];
attributeFilters: number[];
filteringEventAttributeValue: IFilteringAttributeValue;
filteringUserAttributeValue: IFilteringAttributeValue;
filteringConsentRuleValues: IFilteringConsentRulesValue;
filteringEventAttributeValue: IFilteringEventAttributeValue;
filteringUserAttributeValue: IFilteringUserAttributeValue;
filteringConsentRuleValues: IFilteringConsentRuleValues;
consentRegulationFilters: number[];
consentRegulationPurposeFilters: number[];
messageTypeFilters: number[];
Expand All @@ -40,12 +40,18 @@ export interface IKitConfigs {
excludeAnonymousUser: boolean;
}

export interface IFilteringAttributeValue {
export interface IFilteringEventAttributeValue {
eventAttributeName: string;
eventAttributeValue: string;
includeOnMatch: boolean
}
export interface IFilteringConsentRulesValue {

export interface IFilteringUserAttributeValue {
userAttributeName: string;
userAttributeValue: string;
includeOnMatch: boolean
}
export interface IFilteringConsentRuleValues {
includeOnMatch: boolean;
values: IConsentRuleValue[];
}
Expand Down
15 changes: 6 additions & 9 deletions src/consent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import {
} from '@mparticle/web-sdk';
import { MParticleUser, MParticleWebSDK } from './sdkRuntimeModels';
import { Dictionary, isObject } from './utils';
import KitFilterHelper from './kitFilterHelper';
import Constants from './constants';

// Specifies to compiler that CCPAPurpose can only be one specific value
export const CCPAPurpose = 'data_sale_opt_out' as const;
const { CCPAPurpose } = Constants;

export interface IMinifiedConsentJSONObject {
gdpr?: Dictionary<IPrivacyV2DTO>;
Expand Down Expand Up @@ -144,25 +145,21 @@ export default function Consent(this: IConsent, mpInstance: MParticleWebSDK) {
// GDPR - '1' + purpose name
// CCPA - '2data_sale_opt_out' (there is only 1 purpose of data_sale_opt_out for CCPA)
const GDPRConsentHashPrefix = '1';
const CCPAHashString = '2' + CCPAPurpose;
const CCPAHashPrefix = '2';

const gdprConsentState = consentState.getGDPRConsentState();
if (gdprConsentState) {
for (const purpose in gdprConsentState) {
if (gdprConsentState.hasOwnProperty(purpose)) {
purposeHash = mpInstance._Helpers
.generateHash(GDPRConsentHashPrefix + purpose)
.toString();
purposeHash = KitFilterHelper.hashConsentPurposeConditionalForwarding(GDPRConsentHashPrefix, purpose);
purposeHashes[purposeHash] =
gdprConsentState[purpose].Consented;
}
}
}
const CCPAConsentState = consentState.getCCPAConsentState();
if (CCPAConsentState) {
purposeHash = mpInstance._Helpers
.generateHash(CCPAHashString)
.toString();
purposeHash = KitFilterHelper.hashConsentPurposeConditionalForwarding(CCPAHashPrefix, CCPAPurpose);
purposeHashes[purposeHash] = CCPAConsentState.Consented;
}
}
Expand Down
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ const Constants = {
OfflineStorage: 'offlineStorage',
},
DefaultInstance: 'default_instance',
CCPAPurpose: 'data_sale_opt_out'
} as const;

export default Constants;
44 changes: 24 additions & 20 deletions src/forwarders.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Types from './types';
import filteredMparticleUser from './filteredMparticleUser';
import { isEmpty } from './utils';
import KitFilterHelper from './kitFilterHelper';

export default function Forwarders(mpInstance, kitBlocker) {
var self = this;
Expand Down Expand Up @@ -110,12 +111,12 @@ export default function Forwarders(mpInstance, kitBlocker) {
) {
for (var attrName in userAttributes) {
if (userAttributes.hasOwnProperty(attrName)) {
attrHash = mpInstance._Helpers
.generateHash(attrName)
.toString();
valueHash = mpInstance._Helpers
.generateHash(userAttributes[attrName])
.toString();
attrHash = KitFilterHelper.hashAttributeConditionalForwarding(
attrName
);
valueHash = KitFilterHelper.hashAttributeConditionalForwarding(
userAttributes[attrName]
);

if (
attrHash === filterObject.userAttributeName &&
Expand Down Expand Up @@ -177,7 +178,9 @@ export default function Forwarders(mpInstance, kitBlocker) {
if (
mpInstance._Helpers.inArray(
filterList,
userIdentity.Type
KitFilterHelper.hashUserIdentity(
userIdentity.Type
)
)
) {
event.UserIdentities.splice(i, 1);
Expand All @@ -198,8 +201,10 @@ export default function Forwarders(mpInstance, kitBlocker) {

for (var attrName in event.EventAttributes) {
if (event.EventAttributes.hasOwnProperty(attrName)) {
hash = mpInstance._Helpers.generateHash(
event.EventCategory + event.EventName + attrName
hash = KitFilterHelper.hashEventAttributeKey(
event.EventCategory,
event.EventName,
attrName
);

if (mpInstance._Helpers.inArray(filterList, hash)) {
Expand Down Expand Up @@ -227,10 +232,11 @@ export default function Forwarders(mpInstance, kitBlocker) {
!mpInstance._Store.webviewBridgeEnabled &&
mpInstance._Store.activeForwarders
) {
hashedEventName = mpInstance._Helpers.generateHash(
event.EventCategory + event.EventName
hashedEventName = KitFilterHelper.hashEventName(
event.EventName,
event.EventCategory
);
hashedEventType = mpInstance._Helpers.generateHash(
hashedEventType = KitFilterHelper.hashEventType(
event.EventCategory
);

Expand Down Expand Up @@ -261,9 +267,9 @@ export default function Forwarders(mpInstance, kitBlocker) {
if (event.EventAttributes) {
for (var prop in event.EventAttributes) {
var hashedEventAttributeName;
hashedEventAttributeName = mpInstance._Helpers
.generateHash(prop)
.toString();
hashedEventAttributeName = KitFilterHelper.hashAttributeConditionalForwarding(
prop
);

if (
hashedEventAttributeName ===
Expand All @@ -273,11 +279,9 @@ export default function Forwarders(mpInstance, kitBlocker) {
) {
foundProp = {
name: hashedEventAttributeName,
value: mpInstance._Helpers
.generateHash(
event.EventAttributes[prop]
)
.toString(),
value: KitFilterHelper.hashAttributeConditionalForwarding(
event.EventAttributes[prop]
),
};
}

Expand Down
17 changes: 11 additions & 6 deletions src/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Types from './types';
import Constants from './constants';
import * as utils from './utils';
import Validators from './validators';
import KitFilterHelper from './kitFilterHelper';

var StorageNames = Constants.StorageNames;

Expand Down Expand Up @@ -306,13 +307,13 @@ export default function Helpers(mpInstance) {
userIdentitiesObject,
filterList
) {
var filteredUserIdentities = {};
const filteredUserIdentities = {};

if (userIdentitiesObject && Object.keys(userIdentitiesObject).length) {
for (var userIdentityName in userIdentitiesObject) {
for (const userIdentityName in userIdentitiesObject) {
if (userIdentitiesObject.hasOwnProperty(userIdentityName)) {
var userIdentityType = Types.IdentityType.getIdentityType(
userIdentityName
const userIdentityType = KitFilterHelper.hashUserIdentity(
Types.IdentityType.getIdentityType(userIdentityName)
);
if (!self.inArray(filterList, userIdentityType)) {
filteredUserIdentities[userIdentityName] =
Expand All @@ -331,7 +332,9 @@ export default function Helpers(mpInstance) {
if (userAttributes && Object.keys(userAttributes).length) {
for (var userAttribute in userAttributes) {
if (userAttributes.hasOwnProperty(userAttribute)) {
var hashedUserAttribute = self.generateHash(userAttribute);
const hashedUserAttribute = KitFilterHelper.hashUserAttribute(
userAttribute
);
if (!self.inArray(filterList, hashedUserAttribute)) {
filteredUserAttributes[userAttribute] =
userAttributes[userAttribute];
Expand All @@ -344,7 +347,9 @@ export default function Helpers(mpInstance) {
};

this.isFilteredUserAttribute = function(userAttributeKey, filterList) {
const hashedUserAttribute = self.generateHash(userAttributeKey);
const hashedUserAttribute = KitFilterHelper.hashUserAttribute(
userAttributeKey
);
return filterList && self.inArray(filterList, hashedUserAttribute);
};

Expand Down
47 changes: 47 additions & 0 deletions src/kitFilterHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { generateHash } from "./utils";
// TODO: https://mparticle-eng.atlassian.net/browse/SQDSDKS-5381
import { EventTypeEnum, IdentityType } from "./types.interfaces";
import Constants from './constants';

export default class KitFilterHelper {
static hashEventType(eventType: EventTypeEnum): number {
return generateHash(eventType as unknown as string);
};

static hashEventName(eventName: string, eventType: EventTypeEnum): number {
return generateHash(eventType + eventName);
};

static hashEventAttributeKey(eventType: EventTypeEnum, eventName: string, customAttributeName: string): number {
return generateHash(eventType + eventName + customAttributeName);
}

static hashUserAttribute(userAttributeKey: string): number {
return generateHash(userAttributeKey);
}

// User Identities are not actually hashed, this method is named this way to
// be consistent with the filter class. UserIdentityType is also a number
static hashUserIdentity(userIdentity: IdentityType): IdentityType {
return userIdentity;
}

static hashConsentPurpose(prefix: string, purpose: string){
return generateHash(prefix + purpose)

}

// The methods below are for conditional forwarding, a type of filter
// hashAttributeCondiitonalForwarding is used for both User and Event
// attribute keys and attribute values
// The backend returns the hashes as strings for conditional forwarding
// but returns "regular" filters as arrays of numbers
// See IFilteringEventAttributeValue in configApiClient.ts as an example
static hashAttributeConditionalForwarding(attribute: string): string {
return generateHash(attribute).toString();
}

static hashConsentPurposeConditionalForwarding(prefix: string, purpose: string): string {
return this.hashConsentPurpose(prefix, purpose).toString();
}
}
36 changes: 36 additions & 0 deletions src/types.interfaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
export enum EventTypeEnum {
Unknown,
Navigation,
Location,
Search,
Transaction,
UserContent,
UserPreference,
Social,
Other,
Media,
}

export enum IdentityType {
Other = 0,
CustomerId = 1,
Facebook = 2,
Twitter = 3,
Google = 4,
Microsoft = 5,
Yahoo = 6,
Email = 7,
FacebookCustomAudienceId = 9,
Other2 = 10,
Other3 = 11,
Other4 = 12,
Other5 = 13,
Other6 = 14,
Other7 = 15,
Other8 = 16,
Other9 = 17,
Other10 = 18,
MobileNumber = 19,
PhoneNumber2 = 20,
PhoneNumber3 = 21,
}
Loading

0 comments on commit 029f51e

Please sign in to comment.