Skip to content

Commit 410a0c1

Browse files
authored
feat: Add alias for sha256 identities (#1252)
1 parent 1fafa67 commit 410a0c1

9 files changed

Lines changed: 272 additions & 66 deletions

package-lock.json

Lines changed: 8 additions & 53 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@
118118
"@types/jest": "^29.5.1",
119119
"@types/jest-expect-message": "^1.1.0",
120120
"@types/mocha": "^9.0.0",
121-
"@types/mparticle__web-sdk": "^2.16.1",
121+
"@types/mparticle__web-sdk": "^2.66.0",
122122
"@types/node": "^20.1.0",
123123
"babel-preset-minify": "^0.5.1",
124124
"browser-sync": "^2.26.3",

src/identity-utils.ts

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,48 @@ const getExpireTimestamp = (maxAge: number = ONE_DAY_IN_SECONDS): number =>
289289
const parseIdentityResponse = (responseText: string): IdentityResultBody =>
290290
responseText ? JSON.parse(responseText) : ({} as IdentityResultBody);
291291

292+
type Sha256IdentityAlias = 'email_sha256' | 'mobile_sha256';
293+
294+
const SHA256_IDENTITY_ALIASES: Readonly<
295+
Record<Sha256IdentityAlias, keyof UserIdentities>
296+
> = {
297+
email_sha256: 'other',
298+
mobile_sha256: 'other2',
299+
};
300+
301+
type UserIdentitiesWithAliases = UserIdentities &
302+
Partial<Record<Sha256IdentityAlias, string | null>>;
303+
304+
export const normalizeUserIdentityKeys = (
305+
userIdentities: UserIdentitiesWithAliases
306+
): UserIdentities => {
307+
const normalized: UserIdentitiesWithAliases = { ...userIdentities };
308+
(Object.keys(SHA256_IDENTITY_ALIASES) as Sha256IdentityAlias[]).forEach(
309+
(alias) => {
310+
if (alias in normalized) {
311+
const value = normalized[alias];
312+
delete normalized[alias];
313+
normalized[SHA256_IDENTITY_ALIASES[alias]] = value;
314+
}
315+
}
316+
);
317+
return normalized;
318+
};
319+
320+
// Compare two identity objects by key and value, independent of
321+
// object key insertion order. The two sides come from different sources
322+
// (numeric IdentityType iteration vs. partner-provided / alias-normalized
323+
// order)
324+
const identitiesEqual = (
325+
a?: UserIdentities,
326+
b?: UserIdentities
327+
): boolean => {
328+
const aKeys = Object.keys(a ?? {});
329+
const bKeys = Object.keys(b ?? {});
330+
if (aKeys.length !== bKeys.length) return false;
331+
return aKeys.every((key) => a[key] === b[key]);
332+
};
333+
292334
export const hasIdentityRequestChanged = (
293335
currentUser: IMParticleUser,
294336
newIdentityRequest: IdentityApiData
@@ -300,11 +342,11 @@ export const hasIdentityRequestChanged = (
300342
const currentUserIdentities =
301343
currentUser.getUserIdentities().userIdentities;
302344

303-
const newIdentities = newIdentityRequest.userIdentities;
304-
305-
return (
306-
JSON.stringify(currentUserIdentities) !== JSON.stringify(newIdentities)
345+
const newIdentities = normalizeUserIdentityKeys(
346+
newIdentityRequest.userIdentities
307347
);
348+
349+
return !identitiesEqual(currentUserIdentities, newIdentities);
308350
};
309351

310352
/**

src/identity.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
cacheOrClearIdCache,
55
createKnownIdentities,
66
executeSearchRequest,
7+
normalizeUserIdentityKeys,
78
tryCacheIdentity,
89
} from './identity-utils';
910
import AudienceManager from './audienceManager';
@@ -35,11 +36,21 @@ export default function Identity(mpInstance) {
3536
);
3637

3738
// First, remove any falsy identity values and warn about them
38-
const cleanedIdentityApiData = mpInstance._Helpers.Validators.removeFalsyIdentityValues(
39+
const removedFalsyIdentityData = mpInstance._Helpers.Validators.removeFalsyIdentityValues(
3940
identityApiData,
4041
mpInstance.Logger
4142
);
4243

44+
// Normalize convenience aliases (email_sha256 → other, mobile_sha256 → other2)
45+
const cleanedIdentityApiData = removedFalsyIdentityData?.userIdentities
46+
? {
47+
...removedFalsyIdentityData,
48+
userIdentities: normalizeUserIdentityKeys(
49+
removedFalsyIdentityData.userIdentities
50+
),
51+
}
52+
: removedFalsyIdentityData;
53+
4354
var identityValidationResult = mpInstance._Helpers.Validators.validateIdentities(
4455
cleanedIdentityApiData,
4556
method

src/sdkRuntimeModels.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,9 @@ export interface SDKProductAction {
161161
}
162162

163163
export interface SDKProduct {
164-
Sku?: string;
165-
Name?: string;
166-
Price?: number;
164+
Sku: string;
165+
Name: string;
166+
Price: number;
167167
Quantity?: number;
168168
Brand?: string;
169169
Variant?: string;
@@ -173,7 +173,7 @@ export interface SDKProduct {
173173
TotalAmount?: number;
174174

175175
// https://go.mparticle.com/work/SQDSDKS-4801
176-
Attributes?: Record<string, unknown> | null;
176+
Attributes?: Record<string, unknown>;
177177
}
178178

179179
// https://go.mparticle.com/work/SQDSDKS-6949
@@ -306,7 +306,7 @@ export const LogLevelType = {
306306
// Currently, this extends MPConfiguration in @types/mparticle__web-sdk
307307
// and the two will be merged in once the Store module is refactored
308308
export interface SDKInitConfig
309-
extends Omit<MPConfiguration, 'dataPlan' | 'logLevel'> {
309+
extends Omit<MPConfiguration, 'dataPlan' | 'logLevel' | 'identityCallback'> {
310310
dataPlan?: DataPlanConfig | KitBlockerDataPlan; // TODO: These should be eventually split into two different attributes
311311
logLevel?: LogLevelType;
312312

src/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,10 @@ export const IdentityType = {
205205
return IdentityType.PhoneNumber2;
206206
case 'phone_number_3':
207207
return IdentityType.PhoneNumber3;
208+
case 'email_sha256':
209+
return IdentityType.Other;
210+
case 'mobile_sha256':
211+
return IdentityType.Other2;
208212
default:
209213
return false;
210214
}

0 commit comments

Comments
 (0)