@mparticle/web-sdk 2.28.1 → 2.28.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mparticle.common.js +17 -13
- package/dist/mparticle.esm.js +17 -13
- package/dist/mparticle.js +61 -29
- package/package.json +1 -1
- package/src/identity-user-interfaces.ts +8 -0
- package/src/identity-utils.ts +93 -40
- package/src/identity.interfaces.ts +2 -1
- package/src/identity.js +14 -9
- package/src/identityApiClient.js +5 -1
- package/src/utils.ts +2 -0
package/dist/mparticle.common.js
CHANGED
|
@@ -154,13 +154,13 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
|
|
|
154
154
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
155
155
|
};
|
|
156
156
|
|
|
157
|
-
var version = "2.28.
|
|
157
|
+
var version = "2.28.2";
|
|
158
158
|
|
|
159
159
|
var Constants={sdkVersion:version,sdkVendor:"mparticle",platform:"web",Messages:{DeprecationMessages:{MethodIsDeprecatedPostfix:"is a deprecated method and will be removed in future releases",AlternativeMethodPrefix:"Please use the alternate method:"},ErrorMessages:{NoToken:"A token must be specified.",EventNameInvalidType:"Event name must be a valid string value.",EventDataInvalidType:"Event data must be a valid object hash.",LoggingDisabled:"Event logging is currently disabled.",CookieParseError:"Could not parse cookie",EventEmpty:"Event object is null or undefined, cancelling send",APIRequestEmpty:"APIRequest is null or undefined, cancelling send",NoEventType:"Event type must be specified.",TransactionIdRequired:"Transaction ID is required",TransactionRequired:"A transaction attributes object is required",PromotionIdRequired:"Promotion ID is required",BadAttribute:"Attribute value cannot be object or array",BadKey:"Key value cannot be object or array",BadLogPurchase:"Transaction attributes and a product are both required to log a purchase, https://docs.mparticle.com/?javascript#measuring-transactions",AudienceAPINotEnabled:"Your workspace is not enabled to retrieve user audiences."},InformationMessages:{CookieSearch:"Searching for cookie",CookieFound:"Cookie found, parsing values",CookieNotFound:"Cookies not found",CookieSet:"Setting cookie",CookieSync:"Performing cookie sync",SendBegin:"Starting to send event",SendIdentityBegin:"Starting to send event to identity server",SendWindowsPhone:"Sending event to Windows Phone container",SendIOS:"Calling iOS path: ",SendAndroid:"Calling Android JS interface method: ",SendHttp:"Sending event to mParticle HTTP service",SendAliasHttp:"Sending alias request to mParticle HTTP service",SendIdentityHttp:"Sending event to mParticle HTTP service",StartingNewSession:"Starting new Session",StartingLogEvent:"Starting to log event",StartingLogOptOut:"Starting to log user opt in/out",StartingEndSession:"Starting to end session",StartingInitialization:"Starting to initialize",StartingLogCommerceEvent:"Starting to log commerce event",StartingAliasRequest:"Starting to Alias MPIDs",LoadingConfig:"Loading configuration options",AbandonLogEvent:"Cannot log event, logging disabled or developer token not set",AbandonAliasUsers:"Cannot Alias Users, logging disabled or developer token not set",AbandonStartSession:"Cannot start session, logging disabled or developer token not set",AbandonEndSession:"Cannot end session, logging disabled or developer token not set",NoSessionToEnd:"Cannot end session, no active session found"},ValidationMessages:{ModifyIdentityRequestUserIdentitiesPresent:"identityRequests to modify require userIdentities to be present. Request not sent to server. Please fix and try again",IdentityRequesetInvalidKey:"There is an invalid key on your identityRequest object. It can only contain a `userIdentities` object and a `onUserAlias` function. Request not sent to server. Please fix and try again.",OnUserAliasType:"The onUserAlias value must be a function.",UserIdentities:"The userIdentities key must be an object with keys of identityTypes and values of strings. Request not sent to server. Please fix and try again.",UserIdentitiesInvalidKey:"There is an invalid identity key on your `userIdentities` object within the identityRequest. Request not sent to server. Please fix and try again.",UserIdentitiesInvalidValues:"All user identity values must be strings or null. Request not sent to server. Please fix and try again.",AliasMissingMpid:"Alias Request must contain both a destinationMpid and a sourceMpid",AliasNonUniqueMpid:"Alias Request's destinationMpid and sourceMpid must be unique",AliasMissingTime:"Alias Request must have both a startTime and an endTime",AliasStartBeforeEndTime:"Alias Request's endTime must be later than its startTime"}},NativeSdkPaths:{LogEvent:"logEvent",SetUserTag:"setUserTag",RemoveUserTag:"removeUserTag",SetUserAttribute:"setUserAttribute",RemoveUserAttribute:"removeUserAttribute",SetSessionAttribute:"setSessionAttribute",AddToCart:"addToCart",RemoveFromCart:"removeFromCart",ClearCart:"clearCart",LogOut:"logOut",SetUserAttributeList:"setUserAttributeList",RemoveAllUserAttributes:"removeAllUserAttributes",GetUserAttributesLists:"getUserAttributesLists",GetAllUserAttributes:"getAllUserAttributes",Identify:"identify",Logout:"logout",Login:"login",Modify:"modify",Alias:"aliasUsers",Upload:"upload"},StorageNames:{localStorageName:"mprtcl-api",localStorageNameV3:"mprtcl-v3",cookieName:"mprtcl-api",cookieNameV2:"mprtcl-v2",cookieNameV3:"mprtcl-v3",localStorageNameV4:"mprtcl-v4",localStorageProductsV4:"mprtcl-prodv4",cookieNameV4:"mprtcl-v4",currentStorageName:"mprtcl-v4",currentStorageProductsName:"mprtcl-prodv4"},DefaultConfig:{cookieDomain:null,cookieExpiration:365,logLevel:null,timeout:300,sessionTimeout:30,maxProducts:20,forwarderStatsTimeout:5e3,integrationDelayTimeout:5e3,maxCookieSize:3e3,aliasMaxWindow:90,uploadInterval:0// Maximum milliseconds in between batch uploads, below 500 will mean immediate upload. The server returns this as a string, but we are using it as a number internally
|
|
160
160
|
},DefaultBaseUrls:{v1SecureServiceUrl:"jssdks.mparticle.com/v1/JS/",v2SecureServiceUrl:"jssdks.mparticle.com/v2/JS/",v3SecureServiceUrl:"jssdks.mparticle.com/v3/JS/",configUrl:"jssdkcdns.mparticle.com/JS/v2/",identityUrl:"identity.mparticle.com/v1/",aliasUrl:"jssdks.mparticle.com/v1/identity/",userAudienceUrl:"nativesdks.mparticle.com/v1/"},Base64CookieKeys:{csm:1,sa:1,ss:1,ua:1,ui:1,csd:1,ia:1,con:1},// https://go.mparticle.com/work/SQDSDKS-6039
|
|
161
161
|
SDKv2NonMPIDCookieKeys:{gs:1,cu:1,l:1,globalSettings:1,currentUserMPID:1},HTTPCodes:{noHttpCoverage:-1,activeIdentityRequest:-2,activeSession:-3,validationIssue:-4,nativeIdentityRequest:-5,loggingDisabledOrMissingAPIKey:-6,tooManyRequests:429},FeatureFlags:{ReportBatching:"reportBatching",EventBatchingIntervalMillis:"eventBatchingIntervalMillis",OfflineStorage:"offlineStorage",DirectUrlRouting:"directURLRouting",CacheIdentity:"cacheIdentity",AudienceAPI:"audienceAPI"},DefaultInstance:"default_instance",CCPAPurpose:"data_sale_opt_out",IdentityMethods:{Modify:"modify",Logout:"logout",Login:"login",Identify:"identify"}};var ONE_DAY_IN_SECONDS=86400;var MILLIS_IN_ONE_SEC=1e3;
|
|
162
162
|
|
|
163
|
-
var Messages$9=Constants.Messages
|
|
163
|
+
var Messages$9=Constants.Messages;var HTTP_SUCCESS=200;var createCookieString=function(a){return replaceCommasWithPipes(replaceQuotesWithApostrophes(a))},revertCookieString=function(a){return replacePipesWithCommas(replaceApostrophesWithQuotes(a))},inArray=function(a,b){var c=0;if(Array.prototype.indexOf)return 0<=a.indexOf(b,0);for(var d=a.length;c<d;c++)if(c in a&&a[c]===b)return !0;return !1},findKeyInObject=function(a,b){if(b&&a)for(var c in a)if(a.hasOwnProperty(c)&&c.toLowerCase()===b.toLowerCase())return c;return null},generateDeprecationMessage=function(a,b){var c=[a,Messages$9.DeprecationMessages.MethodIsDeprecatedPostfix];return b&&(c.push(b),c.push(Messages$9.DeprecationMessages.MethodIsDeprecatedPostfix)),c.join(" ")};function generateHash(a){var b,c=0;if(void 0===a||null===a)return 0;if(a=a.toString().toLowerCase(),Array.prototype.reduce)return a.split("").reduce(function(c,d){return c=(c<<5)-c+d.charCodeAt(0),c&c},0);if(0===a.length)return c;for(var d=0;d<a.length;d++)b=a.charCodeAt(d),c=(c<<5)-c+b,c&=c;return c}var generateRandomValue=function(){var b,c;return window.crypto&&window.crypto.getRandomValues&&(b=window.crypto.getRandomValues(new Uint8Array(1))),b?(c^b[0]%16>>c/4).toString(16):(c^16*Math.random()>>c/4).toString(16)},generateUniqueId=function(b){return void 0===b&&(b=""),b// if the placeholder was passed, return
|
|
164
164
|
?generateRandomValue()// if the placeholder was passed, return
|
|
165
165
|
:// [1e7] -> // 10000000 +
|
|
166
166
|
// -1e3 -> // -1000 +
|
|
@@ -1089,28 +1089,31 @@ Store:a._Store.serverSettings,SDKVersion:Constants.sdkVersion,SessionId:a._Store
|
|
|
1089
1089
|
|
|
1090
1090
|
function forwardingStatsUploader(a){function b(){var b=a._Forwarders.getForwarderStatsQueue(),c=a._Persistence.forwardingStatsBatches.uploadsTable,d=Date.now();for(var e in b.length&&(c[d]={uploading:!1,data:b},a._Forwarders.setForwarderStatsQueue([])),c)(function(b){if(c.hasOwnProperty(b)&&!1===c[b].uploading){var d=function(){4===e.readyState&&(200===e.status||202===e.status?(a.Logger.verbose("Successfully sent "+e.statusText+" from server"),delete c[b]):"4"===e.status.toString()[0]?429!==e.status&&delete c[b]:c[b].uploading=!1);},e=a._Helpers.createXHR(d),f=c[b].data;c[b].uploading=!0,a._APIClient.sendBatchForwardingStatsToServer(f,e);}})(e);}this.startForwardingStatsTimer=function(){mParticle._forwardingStatsTimer=setInterval(function(){b();},a._Store.SDKConfig.forwarderStatsTimeout);};}
|
|
1091
1091
|
|
|
1092
|
-
var _a=Constants.IdentityMethods,Identify$1=_a.Identify,Modify$2=_a.Modify,Login$1=_a.Login,Logout$1=_a.Logout
|
|
1092
|
+
var _a=Constants.IdentityMethods,Identify$1=_a.Identify,Modify$2=_a.Modify,Login$1=_a.Login,Logout$1=_a.Logout,CACHE_HEADER="x-mp-max-age";// https://go.mparticle.com/work/SQDSDKS-6568
|
|
1093
|
+
// Temporary adapter to convert the XMLHttpRequest response to the IIdentityResponse interface
|
|
1094
|
+
var xhrIdentityResponseAdapter=function(a){return a.hasOwnProperty("expireTimestamp")?a:{status:a.status,// Sometimes responseText can be an empty string, such as a 404 response
|
|
1095
|
+
responseText:a.responseText?JSON.parse(a.responseText):{},cacheMaxAge:parseNumber((null===a||void 0===a?void 0:a.getResponseHeader(CACHE_HEADER))||""),expireTimestamp:0}};var cacheOrClearIdCache=function(a,b,c,d,e){// when parsing a response that has already been cached, simply return instead of attempting another cache
|
|
1093
1096
|
if(!e){// default the expire timestamp to one day in milliseconds unless a header comes back
|
|
1094
|
-
var f=
|
|
1097
|
+
var f=getExpireTimestamp(null===d||void 0===d?void 0:d.cacheMaxAge);a===Login$1||a===Identify$1?cacheIdentityRequest(a,b,f,c,d):a===Modify$2||a===Logout$1?c.purge():void 0;}};var cacheIdentityRequest=function(a,b,c,d,e){var f=e.responseText,g=e.status,h=d.retrieve()||{},i=concatenateIdentities(a,b),j=generateHash(i),k=f.mpid,l=f.is_logged_in;h[j]={responseText:JSON.stringify({mpid:k,is_logged_in:l}),status:g,expireTimestamp:c},d.store(h);};// We need to ensure that identities are concatenated in a deterministic way, so
|
|
1095
1098
|
// we sort the identities based on their enum.
|
|
1096
1099
|
// we create an array, set the user identity at the index of the user identity type
|
|
1097
1100
|
var concatenateIdentities=function(a,b){var c="".concat(a,":").concat("device_application_stamp","=").concat(b.device_application_stamp,";"),d=Object.keys(b).length,e="";// set DAS first since it is not an official identity type
|
|
1098
1101
|
if(d){var f=[];// create an array where each index is equal to the user identity type
|
|
1099
|
-
for(var g in b)if(g==="device_application_stamp")continue;else f[Types.IdentityType.getIdentityType(g)]=b[g];e=f.reduce(function(a,b,c){var d=Types.IdentityType.getIdentityName(c);return "".concat(a).concat(d,"=").concat(b,";")},c);}return e};var hasValidCachedIdentity=function(a,b,c){// There is an edge case where multiple identity calls are taking place
|
|
1100
|
-
// before identify fires, so there may not be a cache. See what happens when
|
|
1102
|
+
for(var g in b)if(g==="device_application_stamp")continue;else f[Types.IdentityType.getIdentityType(g)]=b[g];e=f.reduce(function(a,b,c){var d=Types.IdentityType.getIdentityName(c);return "".concat(a).concat(d,"=").concat(b,";")},c);}return e};var hasValidCachedIdentity=function(a,b,c){// There is an edge case where multiple identity calls are taking place
|
|
1103
|
+
// before identify fires, so there may not be a cache. See what happens when
|
|
1101
1104
|
// the ? in idCache is removed to the following test
|
|
1102
|
-
// "queued events contain login mpid instead of identify mpid when calling
|
|
1105
|
+
// "queued events contain login mpid instead of identify mpid when calling
|
|
1103
1106
|
// login immediately after mParticle initializes"
|
|
1104
1107
|
var d=null===c||void 0===c?void 0:c.retrieve();// if there is no cache, then there is no valid cached identity
|
|
1105
1108
|
if(!d)return !1;var e=concatenateIdentities(a,b),f=generateHash(e);// if cache doesn't have the cacheKey, there is no valid cached identity
|
|
1106
1109
|
if(!d.hasOwnProperty(f))return !1;// If there is a valid cache key, compare the expireTimestamp to the current time.
|
|
1107
1110
|
// If the current time is greater than the expireTimestamp, it is not a valid
|
|
1108
1111
|
// cached identity.
|
|
1109
|
-
var g=d[f].expireTimestamp;return !(g<new Date().getTime())};var getCachedIdentity=function(a,b,c){var d=concatenateIdentities(a,b),e=generateHash(d),f=c.retrieve(),g=f?f[e]:null;return g};// https://go.mparticle.com/work/SQDSDKS-6079
|
|
1112
|
+
var g=d[f].expireTimestamp;return !(g<new Date().getTime())};var getCachedIdentity=function(a,b,c){var d=concatenateIdentities(a,b),e=generateHash(d),f=c.retrieve(),g=f?f[e]:null;return {responseText:parseIdentityResponse(g.responseText),expireTimestamp:g.expireTimestamp,status:g.status}};// https://go.mparticle.com/work/SQDSDKS-6079
|
|
1110
1113
|
var createKnownIdentities=function(a,b){var c={};if(isObject(null===a||void 0===a?void 0:a.userIdentities))for(var d in a.userIdentities)c[d]=a.userIdentities[d];return c.device_application_stamp=b,c};var removeExpiredIdentityCacheDates=function(a){var b=a.retrieve()||{},c=new Date().getTime();// Iterate over the cache and remove any key/value pairs that are expired
|
|
1111
1114
|
for(var d in b)b[d].expireTimestamp<c&&delete b[d];a.store(b);};var tryCacheIdentity=function(a,b,c,d,e,f,g){// https://go.mparticle.com/work/SQDSDKS-6095
|
|
1112
1115
|
var h=hasValidCachedIdentity(g,a,b);// If Identity is cached, then immediately parse the identity response
|
|
1113
|
-
if(h){var i=getCachedIdentity(g,a,b);return c(i,d,e,f,g,a,!0),!0}return !1};
|
|
1116
|
+
if(h){var i=getCachedIdentity(g,a,b);return c(i,d,e,f,g,a,!0),!0}return !1};var getExpireTimestamp=function(a){return void 0===a&&(a=ONE_DAY_IN_SECONDS),new Date().getTime()+a*MILLIS_IN_ONE_SEC},parseIdentityResponse=function(a){return a?JSON.parse(a):{}};
|
|
1114
1117
|
|
|
1115
1118
|
var AudienceManager=/** @class */function(){function a(a,b,c){this.url="",this.logger=c,this.url="https://".concat(a).concat(b,"/audience"),this.userAudienceAPI=window.fetch?new FetchUploader(this.url):new XHRUploader(this.url);}return a.prototype.sendGetUserAudienceRequest=function(a,b){return __awaiter(this,void 0,void 0,function(){var c,d,e,f,g,h;return __generator(this,function(i){switch(i.label){case 0:this.logger.verbose("Fetching user audiences from server"),c={method:"GET",headers:{Accept:"*/*"}},d="".concat(this.url,"?mpid=").concat(a),i.label=1;case 1:return i.trys.push([1,6,,7]),[4/*yield*/,this.userAudienceAPI.upload(c,d)];case 2:return (e=i.sent(),!(200<=e.status&&300>e.status))?[3/*break*/,4]:(this.logger.verbose("User Audiences successfully received"),[4/*yield*/,e.json()]);case 3:f=i.sent(),g={currentAudienceMemberships:null===f||void 0===f?void 0:f.audience_memberships};try{b(g);}catch(a){throw new Error("Error invoking callback on user audience response.")}return [3/*break*/,5];case 4:if(401===e.status)throw new Error("`HTTP error status ${userAudiencePromise.status} while retrieving User Audiences - please verify your API key.`");else if(403===e.status)throw new Error("`HTTP error status ${userAudiencePromise.status} while retrieving User Audiences - please verify your workspace is enabled for audiences.`");else// In case there is an HTTP error we did not anticipate.
|
|
1116
1119
|
throw new Error("Uncaught HTTP Error ".concat(e.status,"."));case 5:return [3/*break*/,7];case 6:return h=i.sent(),this.logger.error("Error retrieving audiences. ".concat(h)),[3/*break*/,7];case 7:return [2/*return*/]}})})},a}();
|
|
@@ -1288,9 +1291,9 @@ return t._Helpers.getFeatureFlag(FeatureFlags$1.AudienceAPI)?void(null===s.audie
|
|
|
1288
1291
|
* @method getCartProducts
|
|
1289
1292
|
* @return {Array} array of cart products
|
|
1290
1293
|
* @deprecated
|
|
1291
|
-
*/getCartProducts:function getCartProducts(){return t.Logger.warning("Deprecated function Identity.getCurrentUser().getCart().getCartProducts() will be removed in future releases"),t._Persistence.getCartProducts(e)}}},this.parseIdentityResponse=function(r,i,a,d,o,g,l){var u,p,y,c=t.Identity.getUser(i),I=c?c.getMPID():null,_=c?c.getUserIdentities().userIdentities:{},v={};t._Store.identityCallInFlight=!1;try{var m,S;if(t.Logger.verbose("Parsing \""+o+"\" identity response from server"),p=
|
|
1292
|
-
n.sendUserIdentityChangeEvent(
|
|
1293
|
-
t.Logger.error("Received HTTP response code of "+r.status+" - "+p.errors[0].message);t.Logger.verbose("Successfully parsed Identity Response"),null===(
|
|
1294
|
+
*/getCartProducts:function getCartProducts(){return t.Logger.warning("Deprecated function Identity.getCurrentUser().getCart().getCartProducts() will be removed in future releases"),t._Persistence.getCartProducts(e)}}},this.parseIdentityResponse=function(r,i,a,d,o,g,l){var u,p,y,c=t.Identity.getUser(i),I=c?c.getMPID():null,_=c?c.getUserIdentities().userIdentities:{},v={};t._Store.identityCallInFlight=!1;try{var m,S,b;if(t.Logger.verbose("Parsing \""+o+"\" identity response from server"),p=null!==(m=r.responseText)&&void 0!==m?m:null,t._Store.isLoggedIn=(null===(S=p)||void 0===S?void 0:S.is_logged_in)||!1,hasMPIDChanged(c,p)&&(t._Store.mpid=p.mpid,c&&t._Persistence.setLastSeenTime(i),u=!t._Persistence.getFirstSeenTime(p.mpid),t._Persistence.setFirstSeenTime(p.mpid)),r.status===HTTP_SUCCESS){if(s(CacheIdentity)){var A=xhrIdentityResponseAdapter(r);cacheOrClearIdCache(o,g,n.idCache,A,l);}var P=n.IdentityAPI.getUser(p.mpid),U=P?P.getUserIdentities().userIdentities:{};o===Modify$1?(v=t._Identity.IdentityRequest.combineUserIdentities(_,d.userIdentities),t._Store.setUserIdentities(i,v)):(o===Identify&&c&&p.mpid===I&&t._Persistence.setFirstSeenTime(p.mpid),t._Store.addMpidToSessionHistory(p.mpid,i),t._CookieSyncManager.attemptCookieSync(i,p.mpid,u),t._Persistence.swapCurrentUser(i,p.mpid,t._Store.currentSessionMPIDs),d&&!isEmpty(d.userIdentities)&&(v=n.IdentityRequest.combineUserIdentities(U,d.userIdentities)),t._Store.setUserIdentities(p.mpid,v),t._Persistence.update(),t._Store.syncPersistenceData(),t._Persistence.findPrevCookiesBasedOnUI(d),t._Store.context=p.context||t._Store.context),y=t.Identity.getCurrentUser(),tryOnUserAlias(c,y,d,t.Logger);var C=t._Persistence.getPersistence();y&&(t._Persistence.storeDataInMemory(C,y.getMPID()),n.reinitForwardersOnUserChange(c,y),n.setForwarderCallbacks(y,o));var k=getNewIdentitiesByName(v),f=o===Modify$1?_:U;// https://go.mparticle.com/work/SQDSDKS-6501
|
|
1295
|
+
n.sendUserIdentityChangeEvent(k,o,p.mpid,f);}if(a){var T=0===r.status?HTTPCodes$2.noHttpCoverage:r.status;t._Helpers.invokeCallback(a,T,p||null,y);}else p&&!isEmpty(p.errors)&&// https://go.mparticle.com/work/SQDSDKS-6500
|
|
1296
|
+
t.Logger.error("Received HTTP response code of "+r.status+" - "+p.errors[0].message);t.Logger.verbose("Successfully parsed Identity Response"),null===(b=t._APIClient)||void 0===b||b.processQueuedEvents();}catch(s){a&&t._Helpers.invokeCallback(a,r.status,p||null),t.Logger.error("Error parsing JSON response from Identity server: "+s);}},this.sendUserIdentityChangeEvent=function(e,r,s,i){if(s||r===Modify$1)// https://go.mparticle.com/work/SQDSDKS-6501
|
|
1294
1297
|
{// https://go.mparticle.com/work/SQDSDKS-6354
|
|
1295
1298
|
var a=this.IdentityAPI.getUser(s);for(var d in e)// Verifies a change actually happened
|
|
1296
1299
|
if(i[d]!==e[d]){var o,g=!i[d],l=n.createUserIdentityChange(d,e[d],i[d],g,a);// If a new identity type was introduced when the identity changes
|
|
@@ -1391,7 +1394,8 @@ var buildUrl=function(a,b,c,d){var e=d?"1":"0",f=["env=".concat(e)],g=c||{},h=g.
|
|
|
1391
1394
|
return [2/*return*/,b]}})})};}
|
|
1392
1395
|
|
|
1393
1396
|
var HTTPCodes$1=Constants.HTTPCodes,Messages$1=Constants.Messages,Modify=Constants.IdentityMethods.Modify;function IdentityAPIClient(a){this.sendAliasRequest=function(b,c){var d,e=function xhrCallback(){if(4===d.readyState){//only parse error messages from failing requests
|
|
1394
|
-
if(a.Logger.verbose("Received "+d.statusText+" from server"),200!==d.status&&202!==d.status&&d.responseText){var b=JSON.parse(d.responseText);if(b.hasOwnProperty("message")){var e=b.message;return void a._Helpers.invokeAliasCallback(c,d.status,e)}}a._Helpers.invokeAliasCallback(c,d.status);}};if(a.Logger.verbose(Messages$1.InformationMessages.SendAliasHttp),d=a._Helpers.createXHR(e),d)try{d.open("post",a._Helpers.createServiceUrl(a._Store.SDKConfig.aliasUrl,a._Store.devToken)+"/Alias"),d.send(JSON.stringify(b));}catch(b){a._Helpers.invokeAliasCallback(c,HTTPCodes$1.noHttpCoverage,b),a.Logger.error("Error sending alias request to mParticle servers. "+b);}},this.sendIdentityRequest=function(b,c,d,e,f,g,h){var i,j,k=function xhrCallback(){4===i.readyState
|
|
1397
|
+
if(a.Logger.verbose("Received "+d.statusText+" from server"),200!==d.status&&202!==d.status&&d.responseText){var b=JSON.parse(d.responseText);if(b.hasOwnProperty("message")){var e=b.message;return void a._Helpers.invokeAliasCallback(c,d.status,e)}}a._Helpers.invokeAliasCallback(c,d.status);}};if(a.Logger.verbose(Messages$1.InformationMessages.SendAliasHttp),d=a._Helpers.createXHR(e),d)try{d.open("post",a._Helpers.createServiceUrl(a._Store.SDKConfig.aliasUrl,a._Store.devToken)+"/Alias"),d.send(JSON.stringify(b));}catch(b){a._Helpers.invokeAliasCallback(c,HTTPCodes$1.noHttpCoverage,b),a.Logger.error("Error sending alias request to mParticle servers. "+b);}},this.sendIdentityRequest=function(b,c,d,e,f,g,h){var i,j,k=function xhrCallback(){if(4===i.readyState){a.Logger.verbose("Received "+i.statusText+" from server");// https://go.mparticle.com/work/SQDSDKS-6565
|
|
1398
|
+
var b=xhrIdentityResponseAdapter(i);f(b,j,d,e,c,h,!1);}};if(a.Logger.verbose(Messages$1.InformationMessages.SendIdentityBegin),!b)return void a.Logger.error(Messages$1.ErrorMessages.APIRequestEmpty);if(a.Logger.verbose(Messages$1.InformationMessages.SendIdentityHttp),i=a._Helpers.createXHR(k),i)try{a._Store.identityCallInFlight?a._Helpers.invokeCallback(d,HTTPCodes$1.activeIdentityRequest,"There is currently an Identity request processing. Please wait for this to return before requesting again"):(j=g||null,c===Modify?i.open("post",a._Helpers.createServiceUrl(a._Store.SDKConfig.identityUrl)+g+"/"+c):i.open("post",a._Helpers.createServiceUrl(a._Store.SDKConfig.identityUrl)+c),i.setRequestHeader("Content-Type","application/json"),i.setRequestHeader("x-mp-key",a._Store.devToken),a._Store.identityCallInFlight=!0,i.send(JSON.stringify(b)));}catch(b){a._Store.identityCallInFlight=!1,a._Helpers.invokeCallback(d,HTTPCodes$1.noHttpCoverage,b),a.Logger.error("Error sending identity request to servers with status code "+i.status+" - "+b);}};}
|
|
1395
1399
|
|
|
1396
1400
|
var Messages=Constants.Messages,HTTPCodes=Constants.HTTPCodes,FeatureFlags=Constants.FeatureFlags,ReportBatching=FeatureFlags.ReportBatching,StartingInitialization=Messages.InformationMessages.StartingInitialization;/**
|
|
1397
1401
|
* <p>All of the following methods can be called on the primary mParticle class. In version 2.10.0, we introduced <a href="https://docs.mparticle.com/developers/sdk/web/multiple-instances/">multiple instances</a>. If you are using multiple instances (self hosted environments only), you should call these methods on each instance.</p>
|
package/dist/mparticle.esm.js
CHANGED
|
@@ -154,13 +154,13 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
|
|
|
154
154
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
155
155
|
};
|
|
156
156
|
|
|
157
|
-
var version = "2.28.
|
|
157
|
+
var version = "2.28.2";
|
|
158
158
|
|
|
159
159
|
var Constants={sdkVersion:version,sdkVendor:"mparticle",platform:"web",Messages:{DeprecationMessages:{MethodIsDeprecatedPostfix:"is a deprecated method and will be removed in future releases",AlternativeMethodPrefix:"Please use the alternate method:"},ErrorMessages:{NoToken:"A token must be specified.",EventNameInvalidType:"Event name must be a valid string value.",EventDataInvalidType:"Event data must be a valid object hash.",LoggingDisabled:"Event logging is currently disabled.",CookieParseError:"Could not parse cookie",EventEmpty:"Event object is null or undefined, cancelling send",APIRequestEmpty:"APIRequest is null or undefined, cancelling send",NoEventType:"Event type must be specified.",TransactionIdRequired:"Transaction ID is required",TransactionRequired:"A transaction attributes object is required",PromotionIdRequired:"Promotion ID is required",BadAttribute:"Attribute value cannot be object or array",BadKey:"Key value cannot be object or array",BadLogPurchase:"Transaction attributes and a product are both required to log a purchase, https://docs.mparticle.com/?javascript#measuring-transactions",AudienceAPINotEnabled:"Your workspace is not enabled to retrieve user audiences."},InformationMessages:{CookieSearch:"Searching for cookie",CookieFound:"Cookie found, parsing values",CookieNotFound:"Cookies not found",CookieSet:"Setting cookie",CookieSync:"Performing cookie sync",SendBegin:"Starting to send event",SendIdentityBegin:"Starting to send event to identity server",SendWindowsPhone:"Sending event to Windows Phone container",SendIOS:"Calling iOS path: ",SendAndroid:"Calling Android JS interface method: ",SendHttp:"Sending event to mParticle HTTP service",SendAliasHttp:"Sending alias request to mParticle HTTP service",SendIdentityHttp:"Sending event to mParticle HTTP service",StartingNewSession:"Starting new Session",StartingLogEvent:"Starting to log event",StartingLogOptOut:"Starting to log user opt in/out",StartingEndSession:"Starting to end session",StartingInitialization:"Starting to initialize",StartingLogCommerceEvent:"Starting to log commerce event",StartingAliasRequest:"Starting to Alias MPIDs",LoadingConfig:"Loading configuration options",AbandonLogEvent:"Cannot log event, logging disabled or developer token not set",AbandonAliasUsers:"Cannot Alias Users, logging disabled or developer token not set",AbandonStartSession:"Cannot start session, logging disabled or developer token not set",AbandonEndSession:"Cannot end session, logging disabled or developer token not set",NoSessionToEnd:"Cannot end session, no active session found"},ValidationMessages:{ModifyIdentityRequestUserIdentitiesPresent:"identityRequests to modify require userIdentities to be present. Request not sent to server. Please fix and try again",IdentityRequesetInvalidKey:"There is an invalid key on your identityRequest object. It can only contain a `userIdentities` object and a `onUserAlias` function. Request not sent to server. Please fix and try again.",OnUserAliasType:"The onUserAlias value must be a function.",UserIdentities:"The userIdentities key must be an object with keys of identityTypes and values of strings. Request not sent to server. Please fix and try again.",UserIdentitiesInvalidKey:"There is an invalid identity key on your `userIdentities` object within the identityRequest. Request not sent to server. Please fix and try again.",UserIdentitiesInvalidValues:"All user identity values must be strings or null. Request not sent to server. Please fix and try again.",AliasMissingMpid:"Alias Request must contain both a destinationMpid and a sourceMpid",AliasNonUniqueMpid:"Alias Request's destinationMpid and sourceMpid must be unique",AliasMissingTime:"Alias Request must have both a startTime and an endTime",AliasStartBeforeEndTime:"Alias Request's endTime must be later than its startTime"}},NativeSdkPaths:{LogEvent:"logEvent",SetUserTag:"setUserTag",RemoveUserTag:"removeUserTag",SetUserAttribute:"setUserAttribute",RemoveUserAttribute:"removeUserAttribute",SetSessionAttribute:"setSessionAttribute",AddToCart:"addToCart",RemoveFromCart:"removeFromCart",ClearCart:"clearCart",LogOut:"logOut",SetUserAttributeList:"setUserAttributeList",RemoveAllUserAttributes:"removeAllUserAttributes",GetUserAttributesLists:"getUserAttributesLists",GetAllUserAttributes:"getAllUserAttributes",Identify:"identify",Logout:"logout",Login:"login",Modify:"modify",Alias:"aliasUsers",Upload:"upload"},StorageNames:{localStorageName:"mprtcl-api",localStorageNameV3:"mprtcl-v3",cookieName:"mprtcl-api",cookieNameV2:"mprtcl-v2",cookieNameV3:"mprtcl-v3",localStorageNameV4:"mprtcl-v4",localStorageProductsV4:"mprtcl-prodv4",cookieNameV4:"mprtcl-v4",currentStorageName:"mprtcl-v4",currentStorageProductsName:"mprtcl-prodv4"},DefaultConfig:{cookieDomain:null,cookieExpiration:365,logLevel:null,timeout:300,sessionTimeout:30,maxProducts:20,forwarderStatsTimeout:5e3,integrationDelayTimeout:5e3,maxCookieSize:3e3,aliasMaxWindow:90,uploadInterval:0// Maximum milliseconds in between batch uploads, below 500 will mean immediate upload. The server returns this as a string, but we are using it as a number internally
|
|
160
160
|
},DefaultBaseUrls:{v1SecureServiceUrl:"jssdks.mparticle.com/v1/JS/",v2SecureServiceUrl:"jssdks.mparticle.com/v2/JS/",v3SecureServiceUrl:"jssdks.mparticle.com/v3/JS/",configUrl:"jssdkcdns.mparticle.com/JS/v2/",identityUrl:"identity.mparticle.com/v1/",aliasUrl:"jssdks.mparticle.com/v1/identity/",userAudienceUrl:"nativesdks.mparticle.com/v1/"},Base64CookieKeys:{csm:1,sa:1,ss:1,ua:1,ui:1,csd:1,ia:1,con:1},// https://go.mparticle.com/work/SQDSDKS-6039
|
|
161
161
|
SDKv2NonMPIDCookieKeys:{gs:1,cu:1,l:1,globalSettings:1,currentUserMPID:1},HTTPCodes:{noHttpCoverage:-1,activeIdentityRequest:-2,activeSession:-3,validationIssue:-4,nativeIdentityRequest:-5,loggingDisabledOrMissingAPIKey:-6,tooManyRequests:429},FeatureFlags:{ReportBatching:"reportBatching",EventBatchingIntervalMillis:"eventBatchingIntervalMillis",OfflineStorage:"offlineStorage",DirectUrlRouting:"directURLRouting",CacheIdentity:"cacheIdentity",AudienceAPI:"audienceAPI"},DefaultInstance:"default_instance",CCPAPurpose:"data_sale_opt_out",IdentityMethods:{Modify:"modify",Logout:"logout",Login:"login",Identify:"identify"}};var ONE_DAY_IN_SECONDS=86400;var MILLIS_IN_ONE_SEC=1e3;
|
|
162
162
|
|
|
163
|
-
var Messages$9=Constants.Messages
|
|
163
|
+
var Messages$9=Constants.Messages;var HTTP_SUCCESS=200;var createCookieString=function(a){return replaceCommasWithPipes(replaceQuotesWithApostrophes(a))},revertCookieString=function(a){return replacePipesWithCommas(replaceApostrophesWithQuotes(a))},inArray=function(a,b){var c=0;if(Array.prototype.indexOf)return 0<=a.indexOf(b,0);for(var d=a.length;c<d;c++)if(c in a&&a[c]===b)return !0;return !1},findKeyInObject=function(a,b){if(b&&a)for(var c in a)if(a.hasOwnProperty(c)&&c.toLowerCase()===b.toLowerCase())return c;return null},generateDeprecationMessage=function(a,b){var c=[a,Messages$9.DeprecationMessages.MethodIsDeprecatedPostfix];return b&&(c.push(b),c.push(Messages$9.DeprecationMessages.MethodIsDeprecatedPostfix)),c.join(" ")};function generateHash(a){var b,c=0;if(void 0===a||null===a)return 0;if(a=a.toString().toLowerCase(),Array.prototype.reduce)return a.split("").reduce(function(c,d){return c=(c<<5)-c+d.charCodeAt(0),c&c},0);if(0===a.length)return c;for(var d=0;d<a.length;d++)b=a.charCodeAt(d),c=(c<<5)-c+b,c&=c;return c}var generateRandomValue=function(){var b,c;return window.crypto&&window.crypto.getRandomValues&&(b=window.crypto.getRandomValues(new Uint8Array(1))),b?(c^b[0]%16>>c/4).toString(16):(c^16*Math.random()>>c/4).toString(16)},generateUniqueId=function(b){return void 0===b&&(b=""),b// if the placeholder was passed, return
|
|
164
164
|
?generateRandomValue()// if the placeholder was passed, return
|
|
165
165
|
:// [1e7] -> // 10000000 +
|
|
166
166
|
// -1e3 -> // -1000 +
|
|
@@ -1089,28 +1089,31 @@ Store:a._Store.serverSettings,SDKVersion:Constants.sdkVersion,SessionId:a._Store
|
|
|
1089
1089
|
|
|
1090
1090
|
function forwardingStatsUploader(a){function b(){var b=a._Forwarders.getForwarderStatsQueue(),c=a._Persistence.forwardingStatsBatches.uploadsTable,d=Date.now();for(var e in b.length&&(c[d]={uploading:!1,data:b},a._Forwarders.setForwarderStatsQueue([])),c)(function(b){if(c.hasOwnProperty(b)&&!1===c[b].uploading){var d=function(){4===e.readyState&&(200===e.status||202===e.status?(a.Logger.verbose("Successfully sent "+e.statusText+" from server"),delete c[b]):"4"===e.status.toString()[0]?429!==e.status&&delete c[b]:c[b].uploading=!1);},e=a._Helpers.createXHR(d),f=c[b].data;c[b].uploading=!0,a._APIClient.sendBatchForwardingStatsToServer(f,e);}})(e);}this.startForwardingStatsTimer=function(){mParticle._forwardingStatsTimer=setInterval(function(){b();},a._Store.SDKConfig.forwarderStatsTimeout);};}
|
|
1091
1091
|
|
|
1092
|
-
var _a=Constants.IdentityMethods,Identify$1=_a.Identify,Modify$2=_a.Modify,Login$1=_a.Login,Logout$1=_a.Logout
|
|
1092
|
+
var _a=Constants.IdentityMethods,Identify$1=_a.Identify,Modify$2=_a.Modify,Login$1=_a.Login,Logout$1=_a.Logout,CACHE_HEADER="x-mp-max-age";// https://go.mparticle.com/work/SQDSDKS-6568
|
|
1093
|
+
// Temporary adapter to convert the XMLHttpRequest response to the IIdentityResponse interface
|
|
1094
|
+
var xhrIdentityResponseAdapter=function(a){return a.hasOwnProperty("expireTimestamp")?a:{status:a.status,// Sometimes responseText can be an empty string, such as a 404 response
|
|
1095
|
+
responseText:a.responseText?JSON.parse(a.responseText):{},cacheMaxAge:parseNumber((null===a||void 0===a?void 0:a.getResponseHeader(CACHE_HEADER))||""),expireTimestamp:0}};var cacheOrClearIdCache=function(a,b,c,d,e){// when parsing a response that has already been cached, simply return instead of attempting another cache
|
|
1093
1096
|
if(!e){// default the expire timestamp to one day in milliseconds unless a header comes back
|
|
1094
|
-
var f=
|
|
1097
|
+
var f=getExpireTimestamp(null===d||void 0===d?void 0:d.cacheMaxAge);a===Login$1||a===Identify$1?cacheIdentityRequest(a,b,f,c,d):a===Modify$2||a===Logout$1?c.purge():void 0;}};var cacheIdentityRequest=function(a,b,c,d,e){var f=e.responseText,g=e.status,h=d.retrieve()||{},i=concatenateIdentities(a,b),j=generateHash(i),k=f.mpid,l=f.is_logged_in;h[j]={responseText:JSON.stringify({mpid:k,is_logged_in:l}),status:g,expireTimestamp:c},d.store(h);};// We need to ensure that identities are concatenated in a deterministic way, so
|
|
1095
1098
|
// we sort the identities based on their enum.
|
|
1096
1099
|
// we create an array, set the user identity at the index of the user identity type
|
|
1097
1100
|
var concatenateIdentities=function(a,b){var c="".concat(a,":").concat("device_application_stamp","=").concat(b.device_application_stamp,";"),d=Object.keys(b).length,e="";// set DAS first since it is not an official identity type
|
|
1098
1101
|
if(d){var f=[];// create an array where each index is equal to the user identity type
|
|
1099
|
-
for(var g in b)if(g==="device_application_stamp")continue;else f[Types.IdentityType.getIdentityType(g)]=b[g];e=f.reduce(function(a,b,c){var d=Types.IdentityType.getIdentityName(c);return "".concat(a).concat(d,"=").concat(b,";")},c);}return e};var hasValidCachedIdentity=function(a,b,c){// There is an edge case where multiple identity calls are taking place
|
|
1100
|
-
// before identify fires, so there may not be a cache. See what happens when
|
|
1102
|
+
for(var g in b)if(g==="device_application_stamp")continue;else f[Types.IdentityType.getIdentityType(g)]=b[g];e=f.reduce(function(a,b,c){var d=Types.IdentityType.getIdentityName(c);return "".concat(a).concat(d,"=").concat(b,";")},c);}return e};var hasValidCachedIdentity=function(a,b,c){// There is an edge case where multiple identity calls are taking place
|
|
1103
|
+
// before identify fires, so there may not be a cache. See what happens when
|
|
1101
1104
|
// the ? in idCache is removed to the following test
|
|
1102
|
-
// "queued events contain login mpid instead of identify mpid when calling
|
|
1105
|
+
// "queued events contain login mpid instead of identify mpid when calling
|
|
1103
1106
|
// login immediately after mParticle initializes"
|
|
1104
1107
|
var d=null===c||void 0===c?void 0:c.retrieve();// if there is no cache, then there is no valid cached identity
|
|
1105
1108
|
if(!d)return !1;var e=concatenateIdentities(a,b),f=generateHash(e);// if cache doesn't have the cacheKey, there is no valid cached identity
|
|
1106
1109
|
if(!d.hasOwnProperty(f))return !1;// If there is a valid cache key, compare the expireTimestamp to the current time.
|
|
1107
1110
|
// If the current time is greater than the expireTimestamp, it is not a valid
|
|
1108
1111
|
// cached identity.
|
|
1109
|
-
var g=d[f].expireTimestamp;return !(g<new Date().getTime())};var getCachedIdentity=function(a,b,c){var d=concatenateIdentities(a,b),e=generateHash(d),f=c.retrieve(),g=f?f[e]:null;return g};// https://go.mparticle.com/work/SQDSDKS-6079
|
|
1112
|
+
var g=d[f].expireTimestamp;return !(g<new Date().getTime())};var getCachedIdentity=function(a,b,c){var d=concatenateIdentities(a,b),e=generateHash(d),f=c.retrieve(),g=f?f[e]:null;return {responseText:parseIdentityResponse(g.responseText),expireTimestamp:g.expireTimestamp,status:g.status}};// https://go.mparticle.com/work/SQDSDKS-6079
|
|
1110
1113
|
var createKnownIdentities=function(a,b){var c={};if(isObject(null===a||void 0===a?void 0:a.userIdentities))for(var d in a.userIdentities)c[d]=a.userIdentities[d];return c.device_application_stamp=b,c};var removeExpiredIdentityCacheDates=function(a){var b=a.retrieve()||{},c=new Date().getTime();// Iterate over the cache and remove any key/value pairs that are expired
|
|
1111
1114
|
for(var d in b)b[d].expireTimestamp<c&&delete b[d];a.store(b);};var tryCacheIdentity=function(a,b,c,d,e,f,g){// https://go.mparticle.com/work/SQDSDKS-6095
|
|
1112
1115
|
var h=hasValidCachedIdentity(g,a,b);// If Identity is cached, then immediately parse the identity response
|
|
1113
|
-
if(h){var i=getCachedIdentity(g,a,b);return c(i,d,e,f,g,a,!0),!0}return !1};
|
|
1116
|
+
if(h){var i=getCachedIdentity(g,a,b);return c(i,d,e,f,g,a,!0),!0}return !1};var getExpireTimestamp=function(a){return void 0===a&&(a=ONE_DAY_IN_SECONDS),new Date().getTime()+a*MILLIS_IN_ONE_SEC},parseIdentityResponse=function(a){return a?JSON.parse(a):{}};
|
|
1114
1117
|
|
|
1115
1118
|
var AudienceManager=/** @class */function(){function a(a,b,c){this.url="",this.logger=c,this.url="https://".concat(a).concat(b,"/audience"),this.userAudienceAPI=window.fetch?new FetchUploader(this.url):new XHRUploader(this.url);}return a.prototype.sendGetUserAudienceRequest=function(a,b){return __awaiter(this,void 0,void 0,function(){var c,d,e,f,g,h;return __generator(this,function(i){switch(i.label){case 0:this.logger.verbose("Fetching user audiences from server"),c={method:"GET",headers:{Accept:"*/*"}},d="".concat(this.url,"?mpid=").concat(a),i.label=1;case 1:return i.trys.push([1,6,,7]),[4/*yield*/,this.userAudienceAPI.upload(c,d)];case 2:return (e=i.sent(),!(200<=e.status&&300>e.status))?[3/*break*/,4]:(this.logger.verbose("User Audiences successfully received"),[4/*yield*/,e.json()]);case 3:f=i.sent(),g={currentAudienceMemberships:null===f||void 0===f?void 0:f.audience_memberships};try{b(g);}catch(a){throw new Error("Error invoking callback on user audience response.")}return [3/*break*/,5];case 4:if(401===e.status)throw new Error("`HTTP error status ${userAudiencePromise.status} while retrieving User Audiences - please verify your API key.`");else if(403===e.status)throw new Error("`HTTP error status ${userAudiencePromise.status} while retrieving User Audiences - please verify your workspace is enabled for audiences.`");else// In case there is an HTTP error we did not anticipate.
|
|
1116
1119
|
throw new Error("Uncaught HTTP Error ".concat(e.status,"."));case 5:return [3/*break*/,7];case 6:return h=i.sent(),this.logger.error("Error retrieving audiences. ".concat(h)),[3/*break*/,7];case 7:return [2/*return*/]}})})},a}();
|
|
@@ -1288,9 +1291,9 @@ return t._Helpers.getFeatureFlag(FeatureFlags$1.AudienceAPI)?void(null===s.audie
|
|
|
1288
1291
|
* @method getCartProducts
|
|
1289
1292
|
* @return {Array} array of cart products
|
|
1290
1293
|
* @deprecated
|
|
1291
|
-
*/getCartProducts:function getCartProducts(){return t.Logger.warning("Deprecated function Identity.getCurrentUser().getCart().getCartProducts() will be removed in future releases"),t._Persistence.getCartProducts(e)}}},this.parseIdentityResponse=function(r,i,a,d,o,g,l){var u,p,y,c=t.Identity.getUser(i),I=c?c.getMPID():null,_=c?c.getUserIdentities().userIdentities:{},v={};t._Store.identityCallInFlight=!1;try{var m,S;if(t.Logger.verbose("Parsing \""+o+"\" identity response from server"),p=
|
|
1292
|
-
n.sendUserIdentityChangeEvent(
|
|
1293
|
-
t.Logger.error("Received HTTP response code of "+r.status+" - "+p.errors[0].message);t.Logger.verbose("Successfully parsed Identity Response"),null===(
|
|
1294
|
+
*/getCartProducts:function getCartProducts(){return t.Logger.warning("Deprecated function Identity.getCurrentUser().getCart().getCartProducts() will be removed in future releases"),t._Persistence.getCartProducts(e)}}},this.parseIdentityResponse=function(r,i,a,d,o,g,l){var u,p,y,c=t.Identity.getUser(i),I=c?c.getMPID():null,_=c?c.getUserIdentities().userIdentities:{},v={};t._Store.identityCallInFlight=!1;try{var m,S,b;if(t.Logger.verbose("Parsing \""+o+"\" identity response from server"),p=null!==(m=r.responseText)&&void 0!==m?m:null,t._Store.isLoggedIn=(null===(S=p)||void 0===S?void 0:S.is_logged_in)||!1,hasMPIDChanged(c,p)&&(t._Store.mpid=p.mpid,c&&t._Persistence.setLastSeenTime(i),u=!t._Persistence.getFirstSeenTime(p.mpid),t._Persistence.setFirstSeenTime(p.mpid)),r.status===HTTP_SUCCESS){if(s(CacheIdentity)){var A=xhrIdentityResponseAdapter(r);cacheOrClearIdCache(o,g,n.idCache,A,l);}var P=n.IdentityAPI.getUser(p.mpid),U=P?P.getUserIdentities().userIdentities:{};o===Modify$1?(v=t._Identity.IdentityRequest.combineUserIdentities(_,d.userIdentities),t._Store.setUserIdentities(i,v)):(o===Identify&&c&&p.mpid===I&&t._Persistence.setFirstSeenTime(p.mpid),t._Store.addMpidToSessionHistory(p.mpid,i),t._CookieSyncManager.attemptCookieSync(i,p.mpid,u),t._Persistence.swapCurrentUser(i,p.mpid,t._Store.currentSessionMPIDs),d&&!isEmpty(d.userIdentities)&&(v=n.IdentityRequest.combineUserIdentities(U,d.userIdentities)),t._Store.setUserIdentities(p.mpid,v),t._Persistence.update(),t._Store.syncPersistenceData(),t._Persistence.findPrevCookiesBasedOnUI(d),t._Store.context=p.context||t._Store.context),y=t.Identity.getCurrentUser(),tryOnUserAlias(c,y,d,t.Logger);var C=t._Persistence.getPersistence();y&&(t._Persistence.storeDataInMemory(C,y.getMPID()),n.reinitForwardersOnUserChange(c,y),n.setForwarderCallbacks(y,o));var k=getNewIdentitiesByName(v),f=o===Modify$1?_:U;// https://go.mparticle.com/work/SQDSDKS-6501
|
|
1295
|
+
n.sendUserIdentityChangeEvent(k,o,p.mpid,f);}if(a){var T=0===r.status?HTTPCodes$2.noHttpCoverage:r.status;t._Helpers.invokeCallback(a,T,p||null,y);}else p&&!isEmpty(p.errors)&&// https://go.mparticle.com/work/SQDSDKS-6500
|
|
1296
|
+
t.Logger.error("Received HTTP response code of "+r.status+" - "+p.errors[0].message);t.Logger.verbose("Successfully parsed Identity Response"),null===(b=t._APIClient)||void 0===b||b.processQueuedEvents();}catch(s){a&&t._Helpers.invokeCallback(a,r.status,p||null),t.Logger.error("Error parsing JSON response from Identity server: "+s);}},this.sendUserIdentityChangeEvent=function(e,r,s,i){if(s||r===Modify$1)// https://go.mparticle.com/work/SQDSDKS-6501
|
|
1294
1297
|
{// https://go.mparticle.com/work/SQDSDKS-6354
|
|
1295
1298
|
var a=this.IdentityAPI.getUser(s);for(var d in e)// Verifies a change actually happened
|
|
1296
1299
|
if(i[d]!==e[d]){var o,g=!i[d],l=n.createUserIdentityChange(d,e[d],i[d],g,a);// If a new identity type was introduced when the identity changes
|
|
@@ -1391,7 +1394,8 @@ var buildUrl=function(a,b,c,d){var e=d?"1":"0",f=["env=".concat(e)],g=c||{},h=g.
|
|
|
1391
1394
|
return [2/*return*/,b]}})})};}
|
|
1392
1395
|
|
|
1393
1396
|
var HTTPCodes$1=Constants.HTTPCodes,Messages$1=Constants.Messages,Modify=Constants.IdentityMethods.Modify;function IdentityAPIClient(a){this.sendAliasRequest=function(b,c){var d,e=function xhrCallback(){if(4===d.readyState){//only parse error messages from failing requests
|
|
1394
|
-
if(a.Logger.verbose("Received "+d.statusText+" from server"),200!==d.status&&202!==d.status&&d.responseText){var b=JSON.parse(d.responseText);if(b.hasOwnProperty("message")){var e=b.message;return void a._Helpers.invokeAliasCallback(c,d.status,e)}}a._Helpers.invokeAliasCallback(c,d.status);}};if(a.Logger.verbose(Messages$1.InformationMessages.SendAliasHttp),d=a._Helpers.createXHR(e),d)try{d.open("post",a._Helpers.createServiceUrl(a._Store.SDKConfig.aliasUrl,a._Store.devToken)+"/Alias"),d.send(JSON.stringify(b));}catch(b){a._Helpers.invokeAliasCallback(c,HTTPCodes$1.noHttpCoverage,b),a.Logger.error("Error sending alias request to mParticle servers. "+b);}},this.sendIdentityRequest=function(b,c,d,e,f,g,h){var i,j,k=function xhrCallback(){4===i.readyState
|
|
1397
|
+
if(a.Logger.verbose("Received "+d.statusText+" from server"),200!==d.status&&202!==d.status&&d.responseText){var b=JSON.parse(d.responseText);if(b.hasOwnProperty("message")){var e=b.message;return void a._Helpers.invokeAliasCallback(c,d.status,e)}}a._Helpers.invokeAliasCallback(c,d.status);}};if(a.Logger.verbose(Messages$1.InformationMessages.SendAliasHttp),d=a._Helpers.createXHR(e),d)try{d.open("post",a._Helpers.createServiceUrl(a._Store.SDKConfig.aliasUrl,a._Store.devToken)+"/Alias"),d.send(JSON.stringify(b));}catch(b){a._Helpers.invokeAliasCallback(c,HTTPCodes$1.noHttpCoverage,b),a.Logger.error("Error sending alias request to mParticle servers. "+b);}},this.sendIdentityRequest=function(b,c,d,e,f,g,h){var i,j,k=function xhrCallback(){if(4===i.readyState){a.Logger.verbose("Received "+i.statusText+" from server");// https://go.mparticle.com/work/SQDSDKS-6565
|
|
1398
|
+
var b=xhrIdentityResponseAdapter(i);f(b,j,d,e,c,h,!1);}};if(a.Logger.verbose(Messages$1.InformationMessages.SendIdentityBegin),!b)return void a.Logger.error(Messages$1.ErrorMessages.APIRequestEmpty);if(a.Logger.verbose(Messages$1.InformationMessages.SendIdentityHttp),i=a._Helpers.createXHR(k),i)try{a._Store.identityCallInFlight?a._Helpers.invokeCallback(d,HTTPCodes$1.activeIdentityRequest,"There is currently an Identity request processing. Please wait for this to return before requesting again"):(j=g||null,c===Modify?i.open("post",a._Helpers.createServiceUrl(a._Store.SDKConfig.identityUrl)+g+"/"+c):i.open("post",a._Helpers.createServiceUrl(a._Store.SDKConfig.identityUrl)+c),i.setRequestHeader("Content-Type","application/json"),i.setRequestHeader("x-mp-key",a._Store.devToken),a._Store.identityCallInFlight=!0,i.send(JSON.stringify(b)));}catch(b){a._Store.identityCallInFlight=!1,a._Helpers.invokeCallback(d,HTTPCodes$1.noHttpCoverage,b),a.Logger.error("Error sending identity request to servers with status code "+i.status+" - "+b);}};}
|
|
1395
1399
|
|
|
1396
1400
|
var Messages=Constants.Messages,HTTPCodes=Constants.HTTPCodes,FeatureFlags=Constants.FeatureFlags,ReportBatching=FeatureFlags.ReportBatching,StartingInitialization=Messages.InformationMessages.StartingInitialization;/**
|
|
1397
1401
|
* <p>All of the following methods can be called on the primary mParticle class. In version 2.10.0, we introduced <a href="https://docs.mparticle.com/developers/sdk/web/multiple-instances/">multiple instances</a>. If you are using multiple instances (self hosted environments only), you should call these methods on each instance.</p>
|
package/dist/mparticle.js
CHANGED
|
@@ -393,7 +393,7 @@ var mParticle = (function () {
|
|
|
393
393
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
394
394
|
};
|
|
395
395
|
|
|
396
|
-
var version = "2.28.
|
|
396
|
+
var version = "2.28.2";
|
|
397
397
|
|
|
398
398
|
var Constants = {
|
|
399
399
|
sdkVersion: version,
|
|
@@ -568,6 +568,7 @@ var mParticle = (function () {
|
|
|
568
568
|
var MILLIS_IN_ONE_SEC = 1000;
|
|
569
569
|
|
|
570
570
|
var Messages$9 = Constants.Messages;
|
|
571
|
+
var HTTP_SUCCESS = 200;
|
|
571
572
|
var createCookieString = function createCookieString(value) {
|
|
572
573
|
return replaceCommasWithPipes(replaceQuotesWithApostrophes(value));
|
|
573
574
|
};
|
|
@@ -6715,22 +6716,35 @@ var mParticle = (function () {
|
|
|
6715
6716
|
Modify$2 = _a.Modify,
|
|
6716
6717
|
Login$1 = _a.Login,
|
|
6717
6718
|
Logout$1 = _a.Logout;
|
|
6718
|
-
var
|
|
6719
|
+
var CACHE_HEADER = 'x-mp-max-age';
|
|
6720
|
+
// https://go.mparticle.com/work/SQDSDKS-6568
|
|
6721
|
+
// Temporary adapter to convert the XMLHttpRequest response to the IIdentityResponse interface
|
|
6722
|
+
var xhrIdentityResponseAdapter = function xhrIdentityResponseAdapter(possiblyXhr) {
|
|
6723
|
+
if (possiblyXhr.hasOwnProperty('expireTimestamp')) {
|
|
6724
|
+
// If there is an `expireTimestamp`, it is an IIdentityResponse object, so just return it. This indicates it was a previously cached value.
|
|
6725
|
+
return possiblyXhr;
|
|
6726
|
+
} else {
|
|
6727
|
+
// If there is no `expireTimestamp`, then it is an XHR object and needs to be parsed.
|
|
6728
|
+
return {
|
|
6729
|
+
status: possiblyXhr.status,
|
|
6730
|
+
// Sometimes responseText can be an empty string, such as a 404 response
|
|
6731
|
+
responseText: possiblyXhr.responseText ? JSON.parse(possiblyXhr.responseText) : {},
|
|
6732
|
+
cacheMaxAge: parseNumber((possiblyXhr === null || possiblyXhr === void 0 ? void 0 : possiblyXhr.getResponseHeader(CACHE_HEADER)) || ''),
|
|
6733
|
+
expireTimestamp: 0
|
|
6734
|
+
};
|
|
6735
|
+
}
|
|
6736
|
+
};
|
|
6737
|
+
var cacheOrClearIdCache = function cacheOrClearIdCache(method, knownIdentities, idCache, identityResponse, parsingCachedResponse) {
|
|
6719
6738
|
// when parsing a response that has already been cached, simply return instead of attempting another cache
|
|
6720
6739
|
if (parsingCachedResponse) {
|
|
6721
6740
|
return;
|
|
6722
6741
|
}
|
|
6723
|
-
var CACHE_HEADER = 'x-mp-max-age';
|
|
6724
6742
|
// default the expire timestamp to one day in milliseconds unless a header comes back
|
|
6725
|
-
var
|
|
6726
|
-
var expireTimestamp = now + ONE_DAY_IN_SECONDS * MILLIS_IN_ONE_SEC;
|
|
6727
|
-
if (xhr.getAllResponseHeaders().includes(CACHE_HEADER)) {
|
|
6728
|
-
expireTimestamp = now + parseNumber(xhr.getResponseHeader(CACHE_HEADER)) * MILLIS_IN_ONE_SEC;
|
|
6729
|
-
}
|
|
6743
|
+
var expireTimestamp = getExpireTimestamp(identityResponse === null || identityResponse === void 0 ? void 0 : identityResponse.cacheMaxAge);
|
|
6730
6744
|
switch (method) {
|
|
6731
6745
|
case Login$1:
|
|
6732
6746
|
case Identify$1:
|
|
6733
|
-
cacheIdentityRequest(method, knownIdentities, expireTimestamp, idCache,
|
|
6747
|
+
cacheIdentityRequest(method, knownIdentities, expireTimestamp, idCache, identityResponse);
|
|
6734
6748
|
break;
|
|
6735
6749
|
case Modify$2:
|
|
6736
6750
|
case Logout$1:
|
|
@@ -6738,20 +6752,21 @@ var mParticle = (function () {
|
|
|
6738
6752
|
break;
|
|
6739
6753
|
}
|
|
6740
6754
|
};
|
|
6741
|
-
var cacheIdentityRequest = function cacheIdentityRequest(method, identities, expireTimestamp, idCache,
|
|
6755
|
+
var cacheIdentityRequest = function cacheIdentityRequest(method, identities, expireTimestamp, idCache, identityResponse) {
|
|
6756
|
+
var responseText = identityResponse.responseText,
|
|
6757
|
+
status = identityResponse.status;
|
|
6742
6758
|
var cache = idCache.retrieve() || {};
|
|
6743
6759
|
var cacheKey = concatenateIdentities(method, identities);
|
|
6744
6760
|
var hashedKey = generateHash(cacheKey);
|
|
6745
|
-
var
|
|
6746
|
-
|
|
6747
|
-
|
|
6748
|
-
var cachedResponseText = {
|
|
6761
|
+
var mpid = responseText.mpid,
|
|
6762
|
+
is_logged_in = responseText.is_logged_in;
|
|
6763
|
+
var cachedResponseBody = {
|
|
6749
6764
|
mpid: mpid,
|
|
6750
6765
|
is_logged_in: is_logged_in
|
|
6751
6766
|
};
|
|
6752
6767
|
cache[hashedKey] = {
|
|
6753
|
-
responseText: JSON.stringify(
|
|
6754
|
-
status:
|
|
6768
|
+
responseText: JSON.stringify(cachedResponseBody),
|
|
6769
|
+
status: status,
|
|
6755
6770
|
expireTimestamp: expireTimestamp
|
|
6756
6771
|
};
|
|
6757
6772
|
idCache.store(cache);
|
|
@@ -6783,10 +6798,10 @@ var mParticle = (function () {
|
|
|
6783
6798
|
return concatenatedIdentities;
|
|
6784
6799
|
};
|
|
6785
6800
|
var hasValidCachedIdentity = function hasValidCachedIdentity(method, proposedUserIdentities, idCache) {
|
|
6786
|
-
// There is an edge case where multiple identity calls are taking place
|
|
6787
|
-
// before identify fires, so there may not be a cache. See what happens when
|
|
6801
|
+
// There is an edge case where multiple identity calls are taking place
|
|
6802
|
+
// before identify fires, so there may not be a cache. See what happens when
|
|
6788
6803
|
// the ? in idCache is removed to the following test
|
|
6789
|
-
// "queued events contain login mpid instead of identify mpid when calling
|
|
6804
|
+
// "queued events contain login mpid instead of identify mpid when calling
|
|
6790
6805
|
// login immediately after mParticle initializes"
|
|
6791
6806
|
var cache = idCache === null || idCache === void 0 ? void 0 : idCache.retrieve();
|
|
6792
6807
|
// if there is no cache, then there is no valid cached identity
|
|
@@ -6814,7 +6829,11 @@ var mParticle = (function () {
|
|
|
6814
6829
|
var hashedKey = generateHash(cacheKey);
|
|
6815
6830
|
var cache = idCache.retrieve();
|
|
6816
6831
|
var cachedIdentity = cache ? cache[hashedKey] : null;
|
|
6817
|
-
return
|
|
6832
|
+
return {
|
|
6833
|
+
responseText: parseIdentityResponse(cachedIdentity.responseText),
|
|
6834
|
+
expireTimestamp: cachedIdentity.expireTimestamp,
|
|
6835
|
+
status: cachedIdentity.status
|
|
6836
|
+
};
|
|
6818
6837
|
};
|
|
6819
6838
|
// https://go.mparticle.com/work/SQDSDKS-6079
|
|
6820
6839
|
var createKnownIdentities = function createKnownIdentities(identityApiData, deviceId) {
|
|
@@ -6849,6 +6868,15 @@ var mParticle = (function () {
|
|
|
6849
6868
|
}
|
|
6850
6869
|
return false;
|
|
6851
6870
|
};
|
|
6871
|
+
var getExpireTimestamp = function getExpireTimestamp(maxAge) {
|
|
6872
|
+
if (maxAge === void 0) {
|
|
6873
|
+
maxAge = ONE_DAY_IN_SECONDS;
|
|
6874
|
+
}
|
|
6875
|
+
return new Date().getTime() + maxAge * MILLIS_IN_ONE_SEC;
|
|
6876
|
+
};
|
|
6877
|
+
var parseIdentityResponse = function parseIdentityResponse(responseText) {
|
|
6878
|
+
return responseText ? JSON.parse(responseText) : {};
|
|
6879
|
+
};
|
|
6852
6880
|
|
|
6853
6881
|
var AudienceManager = /** @class */function () {
|
|
6854
6882
|
function AudienceManager(userAudienceUrl, apiKey, logger) {
|
|
@@ -7833,7 +7861,7 @@ var mParticle = (function () {
|
|
|
7833
7861
|
};
|
|
7834
7862
|
|
|
7835
7863
|
// https://go.mparticle.com/work/SQDSDKS-6355
|
|
7836
|
-
this.parseIdentityResponse = function (
|
|
7864
|
+
this.parseIdentityResponse = function (identityResponse, previousMPID, callback, identityApiData, method, knownIdentities, parsingCachedResponse) {
|
|
7837
7865
|
var prevUser = mpInstance.Identity.getUser(previousMPID);
|
|
7838
7866
|
var prevUserMPID = prevUser ? prevUser.getMPID() : null;
|
|
7839
7867
|
var previousUIByName = prevUser ? prevUser.getUserIdentities().userIdentities : {};
|
|
@@ -7843,9 +7871,9 @@ var mParticle = (function () {
|
|
|
7843
7871
|
var newIdentitiesByType = {};
|
|
7844
7872
|
mpInstance._Store.identityCallInFlight = false;
|
|
7845
7873
|
try {
|
|
7846
|
-
var _identityApiResult, _mpInstance$_APIClien;
|
|
7874
|
+
var _identityResponse$res, _identityApiResult, _mpInstance$_APIClien;
|
|
7847
7875
|
mpInstance.Logger.verbose('Parsing "' + method + '" identity response from server');
|
|
7848
|
-
identityApiResult =
|
|
7876
|
+
identityApiResult = (_identityResponse$res = identityResponse.responseText) !== null && _identityResponse$res !== void 0 ? _identityResponse$res : null;
|
|
7849
7877
|
mpInstance._Store.isLoggedIn = ((_identityApiResult = identityApiResult) === null || _identityApiResult === void 0 ? void 0 : _identityApiResult.is_logged_in) || false;
|
|
7850
7878
|
|
|
7851
7879
|
// https://go.mparticle.com/work/SQDSDKS-6504
|
|
@@ -7861,9 +7889,10 @@ var mParticle = (function () {
|
|
|
7861
7889
|
// https://go.mparticle.com/work/SQDSDKS-6329
|
|
7862
7890
|
mpInstance._Persistence.setFirstSeenTime(identityApiResult.mpid);
|
|
7863
7891
|
}
|
|
7864
|
-
if (
|
|
7892
|
+
if (identityResponse.status === HTTP_SUCCESS) {
|
|
7865
7893
|
if (getFeatureFlag(CacheIdentity)) {
|
|
7866
|
-
|
|
7894
|
+
var identityResponseForCache = xhrIdentityResponseAdapter(identityResponse);
|
|
7895
|
+
cacheOrClearIdCache(method, knownIdentities, self.idCache, identityResponseForCache, parsingCachedResponse);
|
|
7867
7896
|
}
|
|
7868
7897
|
var incomingUser = self.IdentityAPI.getUser(identityApiResult.mpid);
|
|
7869
7898
|
var incomingUIByName = incomingUser ? incomingUser.getUserIdentities().userIdentities : {};
|
|
@@ -7912,11 +7941,11 @@ var mParticle = (function () {
|
|
|
7912
7941
|
self.sendUserIdentityChangeEvent(newIdentitiesByName, method, identityApiResult.mpid, uiByName);
|
|
7913
7942
|
}
|
|
7914
7943
|
if (callback) {
|
|
7915
|
-
var callbackCode =
|
|
7944
|
+
var callbackCode = identityResponse.status === 0 ? HTTPCodes$2.noHttpCoverage : identityResponse.status;
|
|
7916
7945
|
mpInstance._Helpers.invokeCallback(callback, callbackCode, identityApiResult || null, newUser);
|
|
7917
7946
|
} else if (identityApiResult && !isEmpty(identityApiResult.errors)) {
|
|
7918
7947
|
// https://go.mparticle.com/work/SQDSDKS-6500
|
|
7919
|
-
mpInstance.Logger.error('Received HTTP response code of ' +
|
|
7948
|
+
mpInstance.Logger.error('Received HTTP response code of ' + identityResponse.status + ' - ' + identityApiResult.errors[0].message);
|
|
7920
7949
|
}
|
|
7921
7950
|
mpInstance.Logger.verbose('Successfully parsed Identity Response');
|
|
7922
7951
|
|
|
@@ -7924,7 +7953,7 @@ var mParticle = (function () {
|
|
|
7924
7953
|
(_mpInstance$_APIClien = mpInstance._APIClient) === null || _mpInstance$_APIClien === void 0 || _mpInstance$_APIClien.processQueuedEvents();
|
|
7925
7954
|
} catch (e) {
|
|
7926
7955
|
if (callback) {
|
|
7927
|
-
mpInstance._Helpers.invokeCallback(callback,
|
|
7956
|
+
mpInstance._Helpers.invokeCallback(callback, identityResponse.status, identityApiResult || null);
|
|
7928
7957
|
}
|
|
7929
7958
|
mpInstance.Logger.error('Error parsing JSON response from Identity server: ' + e);
|
|
7930
7959
|
}
|
|
@@ -8896,7 +8925,10 @@ var mParticle = (function () {
|
|
|
8896
8925
|
if (xhr.readyState === 4) {
|
|
8897
8926
|
// https://go.mparticle.com/work/SQDSDKS-6368
|
|
8898
8927
|
mpInstance.Logger.verbose('Received ' + xhr.statusText + ' from server');
|
|
8899
|
-
|
|
8928
|
+
|
|
8929
|
+
// https://go.mparticle.com/work/SQDSDKS-6565
|
|
8930
|
+
var identityResponse = xhrIdentityResponseAdapter(xhr);
|
|
8931
|
+
parseIdentityResponse(identityResponse, previousMPID, callback, originalIdentityApiData, method, knownIdentities, false);
|
|
8900
8932
|
}
|
|
8901
8933
|
};
|
|
8902
8934
|
mpInstance.Logger.verbose(Messages$1.InformationMessages.SendIdentityBegin);
|
package/package.json
CHANGED
|
@@ -84,6 +84,14 @@ export interface IdentityCallback {
|
|
|
84
84
|
(result: IdentityResult): void;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
export interface IIdentityResponse {
|
|
88
|
+
// https://go.mparticle.com/work/SQDSDKS-6672
|
|
89
|
+
responseText: IdentityResultBody;
|
|
90
|
+
status: number;
|
|
91
|
+
cacheMaxAge?: number; // Default: 86400
|
|
92
|
+
expireTimestamp?: number;
|
|
93
|
+
}
|
|
94
|
+
|
|
87
95
|
export interface IdentityResult {
|
|
88
96
|
httpCode: typeof HTTPCodes;
|
|
89
97
|
getPreviousUser(): User;
|
package/src/identity-utils.ts
CHANGED
|
@@ -2,62 +2,95 @@ import Constants, { ONE_DAY_IN_SECONDS, MILLIS_IN_ONE_SEC } from './constants';
|
|
|
2
2
|
import { Dictionary, parseNumber, isObject, generateHash } from './utils';
|
|
3
3
|
import { BaseVault } from './vault';
|
|
4
4
|
import Types from './types';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
IdentityApiData,
|
|
7
|
+
UserIdentities,
|
|
8
|
+
IdentityCallback,
|
|
9
|
+
} from '@mparticle/web-sdk';
|
|
6
10
|
import { IdentityAPIMethod } from './identity.interfaces';
|
|
11
|
+
import {
|
|
12
|
+
IdentityResultBody,
|
|
13
|
+
IIdentityResponse,
|
|
14
|
+
} from './identity-user-interfaces';
|
|
7
15
|
|
|
8
16
|
const { Identify, Modify, Login, Logout } = Constants.IdentityMethods;
|
|
17
|
+
const CACHE_HEADER = 'x-mp-max-age' as const;
|
|
9
18
|
|
|
10
19
|
export type IdentityCache = BaseVault<Dictionary<ICachedIdentityCall>>;
|
|
11
20
|
|
|
21
|
+
// https://go.mparticle.com/work/SQDSDKS-6675
|
|
12
22
|
export type IParseCachedIdentityResponse = (
|
|
13
|
-
cachedIdentity:
|
|
23
|
+
cachedIdentity: IIdentityResponse,
|
|
14
24
|
mpid: string,
|
|
15
25
|
callback: IdentityCallback,
|
|
16
26
|
identityApiData: IdentityApiData,
|
|
17
27
|
identityMethod: string,
|
|
18
28
|
knownIdentities: IKnownIdentities,
|
|
19
29
|
fromCachedIdentity: boolean
|
|
20
|
-
) => void
|
|
30
|
+
) => void;
|
|
21
31
|
|
|
22
32
|
export interface IKnownIdentities extends UserIdentities {
|
|
23
33
|
device_application_stamp?: string;
|
|
24
34
|
}
|
|
25
35
|
|
|
26
36
|
export interface ICachedIdentityCall {
|
|
37
|
+
// https://go.mparticle.com/work/SQDSDKS-6672
|
|
27
38
|
responseText: string;
|
|
28
39
|
status: number;
|
|
29
40
|
expireTimestamp: number;
|
|
30
41
|
}
|
|
31
42
|
|
|
43
|
+
// https://go.mparticle.com/work/SQDSDKS-6568
|
|
44
|
+
// Temporary adapter to convert the XMLHttpRequest response to the IIdentityResponse interface
|
|
45
|
+
export const xhrIdentityResponseAdapter = (
|
|
46
|
+
possiblyXhr: XMLHttpRequest | IIdentityResponse
|
|
47
|
+
): IIdentityResponse => {
|
|
48
|
+
if (possiblyXhr.hasOwnProperty('expireTimestamp')) {
|
|
49
|
+
// If there is an `expireTimestamp`, it is an IIdentityResponse object, so just return it. This indicates it was a previously cached value.
|
|
50
|
+
return possiblyXhr as IIdentityResponse;
|
|
51
|
+
} else {
|
|
52
|
+
// If there is no `expireTimestamp`, then it is an XHR object and needs to be parsed.
|
|
53
|
+
return {
|
|
54
|
+
status: possiblyXhr.status,
|
|
55
|
+
|
|
56
|
+
// Sometimes responseText can be an empty string, such as a 404 response
|
|
57
|
+
responseText: (possiblyXhr as XMLHttpRequest).responseText
|
|
58
|
+
? JSON.parse((possiblyXhr as XMLHttpRequest).responseText)
|
|
59
|
+
: {},
|
|
60
|
+
cacheMaxAge: parseNumber(
|
|
61
|
+
(possiblyXhr as XMLHttpRequest)?.getResponseHeader(
|
|
62
|
+
CACHE_HEADER
|
|
63
|
+
) || ''
|
|
64
|
+
),
|
|
65
|
+
expireTimestamp: 0,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
32
70
|
export const cacheOrClearIdCache = (
|
|
33
71
|
method: string,
|
|
34
72
|
knownIdentities: IKnownIdentities,
|
|
35
73
|
idCache: BaseVault<Dictionary<ICachedIdentityCall>>,
|
|
36
|
-
|
|
37
|
-
parsingCachedResponse: boolean
|
|
74
|
+
identityResponse: IIdentityResponse,
|
|
75
|
+
parsingCachedResponse: boolean
|
|
38
76
|
): void => {
|
|
39
77
|
// when parsing a response that has already been cached, simply return instead of attempting another cache
|
|
40
|
-
if (parsingCachedResponse) {
|
|
41
|
-
|
|
42
|
-
|
|
78
|
+
if (parsingCachedResponse) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
43
81
|
|
|
44
82
|
// default the expire timestamp to one day in milliseconds unless a header comes back
|
|
45
|
-
|
|
46
|
-
let expireTimestamp = now + ONE_DAY_IN_SECONDS * MILLIS_IN_ONE_SEC;
|
|
47
|
-
if (xhr.getAllResponseHeaders().includes(CACHE_HEADER)) {
|
|
48
|
-
expireTimestamp =
|
|
49
|
-
now + (parseNumber(xhr.getResponseHeader(CACHE_HEADER)) * MILLIS_IN_ONE_SEC);
|
|
50
|
-
}
|
|
83
|
+
const expireTimestamp = getExpireTimestamp(identityResponse?.cacheMaxAge);
|
|
51
84
|
|
|
52
85
|
switch (method) {
|
|
53
|
-
case Login:
|
|
54
|
-
case Identify:
|
|
86
|
+
case Login:
|
|
87
|
+
case Identify:
|
|
55
88
|
cacheIdentityRequest(
|
|
56
89
|
method,
|
|
57
90
|
knownIdentities,
|
|
58
91
|
expireTimestamp,
|
|
59
92
|
idCache,
|
|
60
|
-
|
|
93
|
+
identityResponse
|
|
61
94
|
);
|
|
62
95
|
break;
|
|
63
96
|
case Modify:
|
|
@@ -65,26 +98,32 @@ export const cacheOrClearIdCache = (
|
|
|
65
98
|
idCache.purge();
|
|
66
99
|
break;
|
|
67
100
|
}
|
|
68
|
-
}
|
|
101
|
+
};
|
|
69
102
|
|
|
70
103
|
export const cacheIdentityRequest = (
|
|
71
104
|
method: IdentityAPIMethod,
|
|
72
105
|
identities: IKnownIdentities,
|
|
73
106
|
expireTimestamp: number,
|
|
74
107
|
idCache: IdentityCache,
|
|
75
|
-
|
|
108
|
+
identityResponse: IIdentityResponse
|
|
76
109
|
): void => {
|
|
77
|
-
const
|
|
110
|
+
const { responseText, status } = identityResponse;
|
|
111
|
+
const cache: Dictionary<ICachedIdentityCall> =
|
|
112
|
+
idCache.retrieve() || ({} as Dictionary<ICachedIdentityCall>);
|
|
78
113
|
const cacheKey = concatenateIdentities(method, identities);
|
|
79
114
|
const hashedKey = generateHash(cacheKey);
|
|
80
115
|
|
|
81
|
-
const { mpid, is_logged_in } =
|
|
82
|
-
const
|
|
116
|
+
const { mpid, is_logged_in } = responseText;
|
|
117
|
+
const cachedResponseBody = {
|
|
83
118
|
mpid,
|
|
84
119
|
is_logged_in,
|
|
85
120
|
};
|
|
86
121
|
|
|
87
|
-
cache[hashedKey] = {
|
|
122
|
+
cache[hashedKey] = {
|
|
123
|
+
responseText: JSON.stringify(cachedResponseBody),
|
|
124
|
+
status,
|
|
125
|
+
expireTimestamp,
|
|
126
|
+
};
|
|
88
127
|
idCache.store(cache);
|
|
89
128
|
};
|
|
90
129
|
|
|
@@ -115,7 +154,8 @@ export const concatenateIdentities = (
|
|
|
115
154
|
|
|
116
155
|
concatenatedIdentities = userIDArray.reduce(
|
|
117
156
|
(prevValue: string, currentValue: string, index: number) => {
|
|
118
|
-
const idName: string =
|
|
157
|
+
const idName: string =
|
|
158
|
+
Types.IdentityType.getIdentityName(index);
|
|
119
159
|
return `${prevValue}${idName}=${currentValue};`;
|
|
120
160
|
},
|
|
121
161
|
cacheKey
|
|
@@ -128,12 +168,12 @@ export const concatenateIdentities = (
|
|
|
128
168
|
export const hasValidCachedIdentity = (
|
|
129
169
|
method: IdentityAPIMethod,
|
|
130
170
|
proposedUserIdentities: IKnownIdentities,
|
|
131
|
-
idCache?: IdentityCache
|
|
171
|
+
idCache?: IdentityCache
|
|
132
172
|
): boolean => {
|
|
133
|
-
// There is an edge case where multiple identity calls are taking place
|
|
134
|
-
// before identify fires, so there may not be a cache. See what happens when
|
|
173
|
+
// There is an edge case where multiple identity calls are taking place
|
|
174
|
+
// before identify fires, so there may not be a cache. See what happens when
|
|
135
175
|
// the ? in idCache is removed to the following test
|
|
136
|
-
// "queued events contain login mpid instead of identify mpid when calling
|
|
176
|
+
// "queued events contain login mpid instead of identify mpid when calling
|
|
137
177
|
// login immediately after mParticle initializes"
|
|
138
178
|
const cache = idCache?.retrieve();
|
|
139
179
|
|
|
@@ -152,12 +192,12 @@ export const hasValidCachedIdentity = (
|
|
|
152
192
|
if (!cache.hasOwnProperty(hashedKey)) {
|
|
153
193
|
return false;
|
|
154
194
|
}
|
|
155
|
-
|
|
195
|
+
|
|
156
196
|
// If there is a valid cache key, compare the expireTimestamp to the current time.
|
|
157
197
|
// If the current time is greater than the expireTimestamp, it is not a valid
|
|
158
198
|
// cached identity.
|
|
159
199
|
const expireTimestamp = cache[hashedKey].expireTimestamp;
|
|
160
|
-
|
|
200
|
+
|
|
161
201
|
if (expireTimestamp < new Date().getTime()) {
|
|
162
202
|
return false;
|
|
163
203
|
} else {
|
|
@@ -168,8 +208,8 @@ export const hasValidCachedIdentity = (
|
|
|
168
208
|
export const getCachedIdentity = (
|
|
169
209
|
method: IdentityAPIMethod,
|
|
170
210
|
proposedUserIdentities: IKnownIdentities,
|
|
171
|
-
idCache: IdentityCache
|
|
172
|
-
):
|
|
211
|
+
idCache: IdentityCache
|
|
212
|
+
): IIdentityResponse | null => {
|
|
173
213
|
const cacheKey: string = concatenateIdentities(
|
|
174
214
|
method,
|
|
175
215
|
proposedUserIdentities
|
|
@@ -179,7 +219,11 @@ export const getCachedIdentity = (
|
|
|
179
219
|
const cache = idCache.retrieve();
|
|
180
220
|
const cachedIdentity = cache ? cache[hashedKey] : null;
|
|
181
221
|
|
|
182
|
-
return
|
|
222
|
+
return {
|
|
223
|
+
responseText: parseIdentityResponse(cachedIdentity.responseText),
|
|
224
|
+
expireTimestamp: cachedIdentity.expireTimestamp,
|
|
225
|
+
status: cachedIdentity.status,
|
|
226
|
+
};
|
|
183
227
|
};
|
|
184
228
|
|
|
185
229
|
// https://go.mparticle.com/work/SQDSDKS-6079
|
|
@@ -200,9 +244,12 @@ export const createKnownIdentities = (
|
|
|
200
244
|
return identitiesResult;
|
|
201
245
|
};
|
|
202
246
|
|
|
203
|
-
export const removeExpiredIdentityCacheDates = (
|
|
204
|
-
|
|
205
|
-
|
|
247
|
+
export const removeExpiredIdentityCacheDates = (
|
|
248
|
+
idCache: BaseVault<Dictionary<ICachedIdentityCall>>
|
|
249
|
+
) => {
|
|
250
|
+
const cache: Dictionary<ICachedIdentityCall> =
|
|
251
|
+
idCache.retrieve() || ({} as Dictionary<ICachedIdentityCall>);
|
|
252
|
+
|
|
206
253
|
const currentTime: number = new Date().getTime();
|
|
207
254
|
|
|
208
255
|
// Iterate over the cache and remove any key/value pairs that are expired
|
|
@@ -210,10 +257,10 @@ export const removeExpiredIdentityCacheDates = (idCache: BaseVault<Dictionary<IC
|
|
|
210
257
|
if (cache[key].expireTimestamp < currentTime) {
|
|
211
258
|
delete cache[key];
|
|
212
259
|
}
|
|
213
|
-
}
|
|
260
|
+
}
|
|
214
261
|
|
|
215
262
|
idCache.store(cache);
|
|
216
|
-
}
|
|
263
|
+
};
|
|
217
264
|
|
|
218
265
|
export const tryCacheIdentity = (
|
|
219
266
|
knownIdentities: IKnownIdentities,
|
|
@@ -223,7 +270,7 @@ export const tryCacheIdentity = (
|
|
|
223
270
|
callback: IdentityCallback,
|
|
224
271
|
identityApiData: IdentityApiData,
|
|
225
272
|
identityMethod: IdentityAPIMethod
|
|
226
|
-
): boolean =>
|
|
273
|
+
): boolean => {
|
|
227
274
|
// https://go.mparticle.com/work/SQDSDKS-6095
|
|
228
275
|
const shouldReturnCachedIdentity = hasValidCachedIdentity(
|
|
229
276
|
identityMethod,
|
|
@@ -252,4 +299,10 @@ export const tryCacheIdentity = (
|
|
|
252
299
|
return true;
|
|
253
300
|
}
|
|
254
301
|
return false;
|
|
255
|
-
}
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
const getExpireTimestamp = (maxAge: number = ONE_DAY_IN_SECONDS): number =>
|
|
305
|
+
new Date().getTime() + maxAge * MILLIS_IN_ONE_SEC;
|
|
306
|
+
|
|
307
|
+
const parseIdentityResponse = (responseText: string): IdentityResultBody =>
|
|
308
|
+
responseText ? JSON.parse(responseText) : ({} as IdentityResultBody);
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
IUserIdentityChangeEvent,
|
|
11
11
|
IMParticleUser,
|
|
12
12
|
mParticleUserCart,
|
|
13
|
+
IIdentityResponse,
|
|
13
14
|
} from './identity-user-interfaces';
|
|
14
15
|
const { platform, sdkVendor, sdkVersion, HTTPCodes } = Constants;
|
|
15
16
|
|
|
@@ -170,7 +171,7 @@ export interface IIdentity {
|
|
|
170
171
|
userInMemory: IMParticleUser
|
|
171
172
|
): IUserIdentityChangeEvent;
|
|
172
173
|
parseIdentityResponse(
|
|
173
|
-
|
|
174
|
+
identityResponse: IIdentityResponse,
|
|
174
175
|
previousMPID: MPID,
|
|
175
176
|
callback: IdentityCallback,
|
|
176
177
|
identityApiData: IdentityApiData,
|
package/src/identity.js
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
cacheOrClearIdCache,
|
|
5
5
|
createKnownIdentities,
|
|
6
6
|
tryCacheIdentity,
|
|
7
|
+
xhrIdentityResponseAdapter,
|
|
7
8
|
} from './identity-utils';
|
|
8
9
|
import AudienceManager from './audienceManager';
|
|
9
10
|
const { Messages, HTTPCodes, FeatureFlags, IdentityMethods } = Constants;
|
|
@@ -12,6 +13,7 @@ const { CacheIdentity } = FeatureFlags;
|
|
|
12
13
|
const { Identify, Modify, Login, Logout } = IdentityMethods;
|
|
13
14
|
import {
|
|
14
15
|
generateDeprecationMessage,
|
|
16
|
+
HTTP_SUCCESS,
|
|
15
17
|
isEmpty,
|
|
16
18
|
isFunction,
|
|
17
19
|
isObject,
|
|
@@ -1460,7 +1462,7 @@ export default function Identity(mpInstance) {
|
|
|
1460
1462
|
|
|
1461
1463
|
// https://go.mparticle.com/work/SQDSDKS-6355
|
|
1462
1464
|
this.parseIdentityResponse = function(
|
|
1463
|
-
|
|
1465
|
+
identityResponse,
|
|
1464
1466
|
previousMPID,
|
|
1465
1467
|
callback,
|
|
1466
1468
|
identityApiData,
|
|
@@ -1486,9 +1488,7 @@ export default function Identity(mpInstance) {
|
|
|
1486
1488
|
'Parsing "' + method + '" identity response from server'
|
|
1487
1489
|
);
|
|
1488
1490
|
|
|
1489
|
-
identityApiResult =
|
|
1490
|
-
? JSON.parse(xhr.responseText)
|
|
1491
|
-
: null;
|
|
1491
|
+
identityApiResult = identityResponse.responseText ?? null;
|
|
1492
1492
|
|
|
1493
1493
|
mpInstance._Store.isLoggedIn =
|
|
1494
1494
|
identityApiResult?.is_logged_in || false;
|
|
@@ -1513,13 +1513,16 @@ export default function Identity(mpInstance) {
|
|
|
1513
1513
|
);
|
|
1514
1514
|
}
|
|
1515
1515
|
|
|
1516
|
-
if (
|
|
1516
|
+
if (identityResponse.status === HTTP_SUCCESS) {
|
|
1517
1517
|
if (getFeatureFlag(CacheIdentity)) {
|
|
1518
|
+
const identityResponseForCache = xhrIdentityResponseAdapter(
|
|
1519
|
+
identityResponse
|
|
1520
|
+
);
|
|
1518
1521
|
cacheOrClearIdCache(
|
|
1519
1522
|
method,
|
|
1520
1523
|
knownIdentities,
|
|
1521
1524
|
self.idCache,
|
|
1522
|
-
|
|
1525
|
+
identityResponseForCache,
|
|
1523
1526
|
parsingCachedResponse
|
|
1524
1527
|
);
|
|
1525
1528
|
}
|
|
@@ -1642,7 +1645,9 @@ export default function Identity(mpInstance) {
|
|
|
1642
1645
|
|
|
1643
1646
|
if (callback) {
|
|
1644
1647
|
const callbackCode =
|
|
1645
|
-
|
|
1648
|
+
identityResponse.status === 0
|
|
1649
|
+
? HTTPCodes.noHttpCoverage
|
|
1650
|
+
: identityResponse.status;
|
|
1646
1651
|
|
|
1647
1652
|
mpInstance._Helpers.invokeCallback(
|
|
1648
1653
|
callback,
|
|
@@ -1657,7 +1662,7 @@ export default function Identity(mpInstance) {
|
|
|
1657
1662
|
// https://go.mparticle.com/work/SQDSDKS-6500
|
|
1658
1663
|
mpInstance.Logger.error(
|
|
1659
1664
|
'Received HTTP response code of ' +
|
|
1660
|
-
|
|
1665
|
+
identityResponse.status +
|
|
1661
1666
|
' - ' +
|
|
1662
1667
|
identityApiResult.errors[0].message
|
|
1663
1668
|
);
|
|
@@ -1671,7 +1676,7 @@ export default function Identity(mpInstance) {
|
|
|
1671
1676
|
if (callback) {
|
|
1672
1677
|
mpInstance._Helpers.invokeCallback(
|
|
1673
1678
|
callback,
|
|
1674
|
-
|
|
1679
|
+
identityResponse.status,
|
|
1675
1680
|
identityApiResult || null
|
|
1676
1681
|
);
|
|
1677
1682
|
}
|
package/src/identityApiClient.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Constants from './constants';
|
|
2
|
+
import { xhrIdentityResponseAdapter } from './identity-utils';
|
|
2
3
|
|
|
3
4
|
var HTTPCodes = Constants.HTTPCodes,
|
|
4
5
|
Messages = Constants.Messages;
|
|
@@ -78,8 +79,11 @@ export default function IdentityAPIClient(mpInstance) {
|
|
|
78
79
|
mpInstance.Logger.verbose(
|
|
79
80
|
'Received ' + xhr.statusText + ' from server'
|
|
80
81
|
);
|
|
82
|
+
|
|
83
|
+
// https://go.mparticle.com/work/SQDSDKS-6565
|
|
84
|
+
const identityResponse = xhrIdentityResponseAdapter(xhr);
|
|
81
85
|
parseIdentityResponse(
|
|
82
|
-
|
|
86
|
+
identityResponse,
|
|
83
87
|
previousMPID,
|
|
84
88
|
callback,
|
|
85
89
|
originalIdentityApiData,
|
package/src/utils.ts
CHANGED
|
@@ -9,6 +9,8 @@ export type Dictionary<V = any> = Record<string, V>;
|
|
|
9
9
|
|
|
10
10
|
export type Environment = 'development' | 'production';
|
|
11
11
|
|
|
12
|
+
export const HTTP_SUCCESS = 200 as const;
|
|
13
|
+
|
|
12
14
|
const createCookieString = (value: string): string =>
|
|
13
15
|
replaceCommasWithPipes(replaceQuotesWithApostrophes(value));
|
|
14
16
|
|