Skip to content

Commit

Permalink
refactor: Simplify cookie sync manager
Browse files Browse the repository at this point in the history
  • Loading branch information
rmi22186 committed Jan 7, 2025
1 parent c66ec58 commit 9bcac18
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 253 deletions.
139 changes: 58 additions & 81 deletions src/cookieSyncManager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { Dictionary, isEmpty, replaceAmpWithAmpersand, replaceMPID } from './utils';
import {
Dictionary,
isEmpty,
replaceAmpWithAmpersand,
combineUrlWithRedirect,
} from './utils';
import Constants from './constants';
import { MParticleWebSDK } from './sdkRuntimeModels';
import { MPID } from '@mparticle/web-sdk';
Expand All @@ -25,7 +30,6 @@ export interface IPixelConfiguration {
}
export interface ICookieSyncManager {
attemptCookieSync: (
previousMPID: MPID,
mpid: MPID,
mpidIsNotInCookies?: boolean
) => void;
Expand All @@ -34,7 +38,6 @@ export interface ICookieSyncManager {
moduleId: string,
mpid: MPID,
cookieSyncDates: CookieSyncDates,
filteringConsentRuleValues: IConsentRules,
mpidIsNotInCookies: boolean,
requiresConsent: boolean
) => void;
Expand All @@ -47,17 +50,19 @@ export interface ICookieSyncManager {

const hasFrequencyCapExpired = (
frequencyCap: number,
lastSyncDate?: number,
lastSyncDate?: number
): boolean => {
// If there is no lastSyncDate, then there is no previous cookie sync, so we should sync the cookie
if (!lastSyncDate) {
return true;
}

// Otherwise, compare the last sync date to determine if it should do a cookie sync again
return (
new Date().getTime() >
new Date(lastSyncDate).getTime() + frequencyCap * DAYS_IN_MILLISECONDS
);
}
};

export default function CookieSyncManager(
this: ICookieSyncManager,
Expand All @@ -67,17 +72,20 @@ export default function CookieSyncManager(

// Public
this.attemptCookieSync = (
previousMPID: MPID,
mpid: MPID,
mpidIsNotInCookies?: boolean
): void => {
if (!mpid || mpInstance._Store.webviewBridgeEnabled) {
return;
}

const { pixelConfigurations } = mpInstance._Store;
const persistence = mpInstance._Persistence.getPersistence();

if (isEmpty(persistence)) {
return;
}

const { pixelConfigurations } = mpInstance._Store;
pixelConfigurations.forEach((pixelSettings: IPixelConfiguration) => {
// set requiresConsent to false to start each additional pixel configuration
// set to true only if filteringConsenRuleValues.values.length exists
Expand All @@ -91,6 +99,17 @@ export default function CookieSyncManager(
requiresConsent = true;
}

// if MPID is new to cookies, we should not try to perform the cookie sync
// because a cookie sync can only occur once a user either consents or doesn't
// we should not check if its enabled if the user has a blank consent
if (requiresConsent && mpidIsNotInCookies) {
return;
}

if (isEmpty(pixelSettings.pixelUrl) && isEmpty(pixelSettings.redirectUrl)) {
return;
}

// Kit Module ID
const moduleId = pixelSettings.moduleId.toString();

Expand All @@ -104,63 +123,39 @@ export default function CookieSyncManager(
? replaceAmpWithAmpersand(pixelSettings.redirectUrl)
: null;

const urlWithRedirect = this.combineUrlWithRedirect(
const urlWithRedirect = combineUrlWithRedirect(
mpid,
pixelUrl,
redirectUrl
);

if (previousMPID && previousMPID !== mpid) {
if (persistence && persistence[mpid]) {
if (!persistence[mpid].csd) {
persistence[mpid].csd = {};
}
self.performCookieSync(
urlWithRedirect,
moduleId,
mpid,
persistence[mpid].csd,
filteringConsentRuleValues,
mpidIsNotInCookies,
requiresConsent
);
}
return;
} else {
if (!persistence || !persistence[mpid]) {
return;
}

// set up csd object if it doesn't exist
if (persistence && persistence[mpid]) {
if (!persistence[mpid].csd) {
persistence[mpid].csd = {};
}
}

const lastSyncDateForModule = persistence[mpid].csd[moduleId] || null;

// Check to see if we need to refresh cookieSync
if (hasFrequencyCapExpired(frequencyCap, lastSyncDateForModule)) {
self.performCookieSync(
urlWithRedirect,
moduleId,
mpid,
persistence[mpid].csd,
filteringConsentRuleValues,
mpidIsNotInCookies,
requiresConsent
);
}
const lastSyncDateForModule = persistence[mpid].csd[moduleId] || null;

const { isEnabledForUserConsent } = mpInstance._Consent;
if (!isEnabledForUserConsent(filteringConsentRuleValues, mpInstance.Identity.getCurrentUser())) {
return;
}
});
};

this.combineUrlWithRedirect = (
mpid: MPID,
pixelUrl: string,
redirectUrl: string,
): string => {
const url = replaceMPID(pixelUrl, mpid);
const redirect = redirectUrl ? replaceMPID(redirectUrl, mpid) : '';
return url + encodeURIComponent(redirect);
if (!hasFrequencyCapExpired(frequencyCap, lastSyncDateForModule)) {
return;
}

self.performCookieSync(
urlWithRedirect,
moduleId,
mpid,
persistence[mpid].csd,
mpidIsNotInCookies,
requiresConsent
);
});
};

// Private
Expand All @@ -169,35 +164,17 @@ export default function CookieSyncManager(
moduleId: string,
mpid: MPID,
cookieSyncDates: CookieSyncDates,
filteringConsentRuleValues: IConsentRules,
mpidIsNotInCookies: boolean,
requiresConsent: boolean
): void => {
// if MPID is new to cookies, we should not try to perform the cookie sync
// because a cookie sync can only occur once a user either consents or doesn't
// we should not check if its enabled if the user has a blank consent
if (requiresConsent && mpidIsNotInCookies) {
return;
}
const img = document.createElement('img');

if (
// https://go.mparticle.com/work/SQDSDKS-5009
mpInstance._Consent.isEnabledForUserConsent(
filteringConsentRuleValues,
mpInstance.Identity.getCurrentUser()
)
) {
const img = document.createElement('img');

mpInstance.Logger.verbose(InformationMessages.CookieSync);
img.onload = function() {
cookieSyncDates[moduleId] = new Date().getTime();
mpInstance._Persistence.saveUserCookieSyncDatesToPersistence(
mpid,
cookieSyncDates
);
};
img.src = url;
}
mpInstance.Logger.verbose(InformationMessages.CookieSync);
img.onload = function() {
cookieSyncDates[moduleId] = new Date().getTime();
mpInstance._Persistence.saveUserCookieSyncDatesToPersistence(
mpid,
cookieSyncDates
);
};
img.src = url;
};
}
6 changes: 1 addition & 5 deletions src/identity.js
Original file line number Diff line number Diff line change
Expand Up @@ -1230,10 +1230,7 @@ export default function Identity(mpInstance) {
this.getUserIdentities().userIdentities,
mpInstance._APIClient.prepareForwardingStats
);
mpInstance._CookieSyncManager.attemptCookieSync(
null,
this.getMPID()
);
mpInstance._CookieSyncManager.attemptCookieSync(this.getMPID());
},
isLoggedIn: function() {
return isLoggedIn;
Expand Down Expand Up @@ -1562,7 +1559,6 @@ export default function Identity(mpInstance) {
);

mpInstance._CookieSyncManager.attemptCookieSync(
previousMPID,
identityApiResult.mpid,
mpidIsNotInCookies
);
Expand Down
11 changes: 11 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,16 @@ const replaceMPID = (value: string, mpid: MPID): string => value.replace('%%mpid

const replaceAmpWithAmpersand = (value: string): string => value.replace(/&/g, '&');

const combineUrlWithRedirect = (
mpid: MPID,
pixelUrl: string,
redirectUrl: string,
): string => {
const url = replaceMPID(pixelUrl, mpid);
const redirect = redirectUrl ? replaceMPID(redirectUrl, mpid) : '';
return url + encodeURIComponent(redirect);
};

// FIXME: REFACTOR for V3
// only used in store.js to sanitize server-side formatting of
// booleans when checking for `isDevelopmentMode`
Expand Down Expand Up @@ -373,4 +383,5 @@ export {
getHref,
replaceMPID,
replaceAmpWithAmpersand,
combineUrlWithRedirect,
};
Loading

0 comments on commit 9bcac18

Please sign in to comment.