Skip to content

Commit 7f8078b

Browse files
Merge branch 'main' of https://github.com/mParticle/mparticle-web-sdk into refactor/logger-interface
# Conflicts: # src/batchUploader.ts # src/sdkRuntimeModels.ts
2 parents 82cdb86 + 765f3ba commit 7f8078b

19 files changed

Lines changed: 663 additions & 245 deletions

AGENTS.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ mParticle is a Customer Data Platform that collects, validates, and forwards eve
5555
- **No Unnecessary Features**: Don't add error handling for scenarios that can't happen
5656
- **Trust Internal Code**: Only validate at system boundaries (user input, external APIs)
5757

58+
### Logging and PII Obfuscation
59+
60+
**PII (Personally Identifiable Information)** is data that can identify a specific person, for example: email, name or phone number, and similar attributes. Logging raw payloads can expose PII in production.
61+
62+
- Use `obfuscateDevData(data, isDevelopmentMode)` from `utils` to log payloads - shows raw data in development mode, obfuscates in production.
63+
- Use `obfuscateData(data)` from `utils` when you need to obfuscate a specific field.
64+
5865
### Testing Requirements
5966

6067
- Run the full test suite before committing

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
## [2.60.1](https://github.com/mParticle/mparticle-web-sdk/compare/v2.60.0...v2.60.1) (2026-03-25)
2+
3+
4+
### Bug Fixes
5+
6+
* update getSession to use non deprecated method ([#1227](https://github.com/mParticle/mparticle-web-sdk/issues/1227)) ([af259c2](https://github.com/mParticle/mparticle-web-sdk/commit/af259c254e51bccac7d61b5f4f51824659cf3d50))
7+
8+
# [2.60.0](https://github.com/mParticle/mparticle-web-sdk/compare/v2.59.0...v2.60.0) (2026-03-24)
9+
10+
11+
### Features
12+
13+
* Obfuscate potential PII in logs ([#1219](https://github.com/mParticle/mparticle-web-sdk/issues/1219)) ([ccc2cd7](https://github.com/mParticle/mparticle-web-sdk/commit/ccc2cd7ae5446ae052ae30e8913e8670324a4d0d))
14+
115
# [2.59.0](https://github.com/mParticle/mparticle-web-sdk/compare/v2.58.0...v2.59.0) (2026-03-16)
216

317

dist/mparticle.common.js

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

dist/mparticle.esm.js

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

dist/mparticle.js

Lines changed: 141 additions & 84 deletions
Large diffs are not rendered by default.

package-lock.json

Lines changed: 2 additions & 2 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
@@ -1,6 +1,6 @@
11
{
22
"name": "@mparticle/web-sdk",
3-
"version": "2.59.0",
3+
"version": "2.60.1",
44
"description": "mParticle core SDK for web applications",
55
"license": "Apache-2.0",
66
"keywords": [

src/batchUploader.ts

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import { Batch } from '@mparticle/event-models';
22
import Constants from './constants';
33
import { SDKEvent, SDKEventCustomFlags } from './sdkRuntimeModels';
4-
import { ILogger } from './logger';
5-
import { convertEvents } from './sdkToEventsApiConverter';
4+
import { convertEvents} from './sdkToEventsApiConverter';
65
import { MessageType, EventType } from './types';
7-
import { getRampNumber, isEmpty } from './utils';
6+
import { getRampNumber, isEmpty, obfuscateDevData } from './utils';
87
import { SessionStorageVault, LocalStorageVault } from './vault';
98
import {
109
AsyncUploader,
@@ -80,17 +79,11 @@ export class BatchUploader {
8079

8180
if (this.offlineStorageEnabled && !noFunctional) {
8281
this.eventVault = new SessionStorageVault<SDKEvent[]>(
83-
`${mpInstance._Store.storageName}-events`,
84-
{
85-
logger: mpInstance.Logger,
86-
}
82+
`${mpInstance._Store.storageName}-events`
8783
);
8884

8985
this.batchVault = new LocalStorageVault<Batch[]>(
90-
`${mpInstance._Store.storageName}-batches`,
91-
{
92-
logger: mpInstance.Logger,
93-
}
86+
`${mpInstance._Store.storageName}-batches`
9487
);
9588

9689
// Load Events from Session Storage in case we have any in storage
@@ -261,15 +254,16 @@ export class BatchUploader {
261254
return;
262255
}
263256

264-
const { Logger } = this.mpInstance;
265-
266257
this.eventsQueuedForProcessing.push(event);
267258
if (this.offlineStorageEnabled && this.eventVault) {
268259
this.eventVault.store(this.eventsQueuedForProcessing);
269260
}
270261

271-
Logger.verbose(`Queuing event: ${JSON.stringify(event)}`);
272-
Logger.verbose(`Queued event count: ${this.eventsQueuedForProcessing.length}`);
262+
if (this.mpInstance.Logger.isVerbose()) {
263+
const eventToLog = obfuscateDevData(event, this.mpInstance._Store.SDKConfig.isDevelopmentMode);
264+
this.mpInstance.Logger.verbose(`Queuing event: ${JSON.stringify(eventToLog)}`);
265+
this.mpInstance.Logger.verbose(`Queued event count: ${this.eventsQueuedForProcessing.length}`);
266+
}
273267

274268
if (this.shouldTriggerImmediateUpload(event.EventDataType)) {
275269
this.prepareAndUpload(false, false);
@@ -413,7 +407,6 @@ export class BatchUploader {
413407
this.batchesQueuedForProcessing = [];
414408

415409
const batchesThatDidNotUpload = await this.uploadBatches(
416-
this.mpInstance.Logger,
417410
batchesToUpload,
418411
useBeacon
419412
);
@@ -433,8 +426,8 @@ export class BatchUploader {
433426
// therefore NOT overwrite Offline Storage when beacon returns, so that we can retry
434427
// uploading saved batches at a later time. Batches should only be removed from
435428
// Local Storage once we can confirm they are successfully uploaded.
429+
436430
this.batchVault.store(this.batchesQueuedForProcessing);
437-
438431
// Clear batch queue since everything should be in Offline Storage
439432
this.batchesQueuedForProcessing = [];
440433
}
@@ -444,10 +437,7 @@ export class BatchUploader {
444437
}
445438
}
446439

447-
// TODO: Refactor to use logger as a class method
448-
// https://go.mparticle.com/work/SQDSDKS-5167
449440
private async uploadBatches(
450-
logger: ILogger,
451441
batches: Batch[],
452442
useBeacon: boolean
453443
): Promise<Batch[] | null> {
@@ -458,8 +448,11 @@ export class BatchUploader {
458448
return null;
459449
}
460450

461-
logger.verbose(`Uploading batches: ${JSON.stringify(uploads)}`);
462-
logger.verbose(`Batch count: ${uploads.length}`);
451+
if (this.mpInstance.Logger.isVerbose()) {
452+
const uploadsToLog = obfuscateDevData(uploads, this.mpInstance._Store.SDKConfig.isDevelopmentMode);
453+
this.mpInstance.Logger.verbose(`Uploading batches: ${JSON.stringify(uploadsToLog)}`);
454+
this.mpInstance.Logger.verbose(`Batch count: ${uploads.length}`);
455+
}
463456

464457
for (let i = 0; i < uploads.length; i++) {
465458
const fetchPayload: IFetchPayload = {
@@ -483,20 +476,20 @@ export class BatchUploader {
483476
const response = await this.uploader.upload(fetchPayload);
484477

485478
if (response.status >= 200 && response.status < 300) {
486-
logger.verbose(
479+
this.mpInstance.Logger.verbose(
487480
`Upload success for request ID: ${uploads[i].source_request_id}`
488481
);
489482
} else if (
490483
response.status >= 500 ||
491484
response.status === 429
492485
) {
493-
logger.error(
486+
this.mpInstance.Logger.error(
494487
`HTTP error status ${response.status} received`
495488
);
496489
// Server error, add back current batches and try again later
497490
return uploads.slice(i, uploads.length);
498491
} else if (response.status >= 401) {
499-
logger.error(
492+
this.mpInstance.Logger.error(
500493
`HTTP error status ${response.status} while uploading - please verify your API key.`
501494
);
502495
//if we're getting a 401, assume we'll keep getting a 401 and clear the uploads.
@@ -513,7 +506,7 @@ export class BatchUploader {
513506
);
514507
}
515508
} catch (e) {
516-
logger.error(
509+
this.mpInstance.Logger.error(
517510
`Error sending event to mParticle servers. ${e}`
518511
);
519512
return uploads.slice(i, uploads.length);

src/identityApiClient.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
IFetchPayload,
77
} from './uploaders';
88
import { CACHE_HEADER } from './identity-utils';
9-
import { parseNumber, valueof } from './utils';
9+
import { obfuscateData, parseNumber, valueof } from './utils';
1010
import {
1111
IAliasCallback,
1212
IAliasRequest,
@@ -277,9 +277,17 @@ export default function IdentityAPIClient(
277277
message += ' - ' + errorMessage;
278278
}
279279

280-
} else {
281-
message = 'Received Identity Response from server: ';
282-
message += JSON.stringify(identityResponse.responseText);
280+
} else if (Logger.isVerbose()) {
281+
const responseText = identityResponse.responseText;
282+
const { isDevelopmentMode } = mpInstance._Store.SDKConfig;
283+
let responseToLog = responseText;
284+
if (!isDevelopmentMode && responseText?.matched_identities) {
285+
responseToLog = {
286+
...responseText,
287+
matched_identities: obfuscateData(responseText.matched_identities)
288+
};
289+
}
290+
message = 'Received Identity Response from server: ' + JSON.stringify(responseToLog);
283291
}
284292

285293
break;
@@ -306,7 +314,9 @@ export default function IdentityAPIClient(
306314
mpInstance._Store.identityCallInFlight = false;
307315
mpInstance._Store.identityCallFailed = false;
308316

309-
Logger.verbose(message);
317+
if (message) {
318+
Logger.verbose(message);
319+
}
310320
if (mpInstance._RoktManager?.isInitialized) {
311321
const requestCount = mpInstance._Store.identifyRequestCount;
312322
mpInstance.captureTiming(`${requestCount}-identityRequestEnd`);

src/logger.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ export class Logger implements ILogger {
6161
}
6262
}
6363

64+
public isVerbose(): boolean {
65+
return this.logLevel === LogLevelType.Verbose;
66+
}
67+
6468
public setLogLevel(newLogLevel: LogLevelType): void {
6569
this.logLevel = newLogLevel;
6670
}

0 commit comments

Comments
 (0)