@mparticle/web-sdk 2.28.0 → 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 +423 -35
- package/dist/mparticle.esm.js +423 -35
- package/dist/mparticle.js +513 -69
- package/package.json +1 -1
- package/src/apiClient.ts +43 -42
- package/src/forwarders.js +32 -0
- 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/persistence.interfaces.ts +2 -2
- package/src/sdkRuntimeModels.ts +1 -0
- package/src/utils.ts +2 -0
package/package.json
CHANGED
package/src/apiClient.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import Constants from './constants';
|
|
2
2
|
import Types from './types';
|
|
3
3
|
import { BatchUploader } from './batchUploader';
|
|
4
|
-
import { MParticleWebSDK, SDKEvent } from './sdkRuntimeModels';
|
|
4
|
+
import { MParticleWebSDK, SDKEvent, SDKDataPlan } from './sdkRuntimeModels';
|
|
5
5
|
import KitBlocker from './kitBlocking';
|
|
6
6
|
import { Dictionary, getRampNumber, isEmpty, parseNumber } from './utils';
|
|
7
7
|
import { IUploadObject } from './serverModel';
|
|
8
8
|
import { MPForwarder } from './forwarders.interfaces';
|
|
9
|
-
import { IMParticleUser } from './identity-user-interfaces';
|
|
10
|
-
|
|
11
|
-
export type ForwardingStatsData = Dictionary<any>;
|
|
9
|
+
import { IMParticleUser, ISDKUserAttributes } from './identity-user-interfaces';
|
|
10
|
+
import { AsyncUploader, FetchUploader, XHRUploader } from './uploaders';
|
|
12
11
|
|
|
13
12
|
export interface IAPIClient {
|
|
14
13
|
uploader: BatchUploader | null;
|
|
@@ -18,18 +17,30 @@ export interface IAPIClient {
|
|
|
18
17
|
sendEventToServer: (event: SDKEvent, _options?: Dictionary<any>) => void;
|
|
19
18
|
sendSingleEventToServer: (event: SDKEvent) => void;
|
|
20
19
|
sendBatchForwardingStatsToServer: (
|
|
21
|
-
forwardingStatsData:
|
|
20
|
+
forwardingStatsData: IForwardingStatsData,
|
|
22
21
|
xhr: XMLHttpRequest
|
|
23
22
|
) => void;
|
|
24
|
-
|
|
25
|
-
forwardingStatsData: ForwardingStatsData
|
|
26
|
-
) => void;
|
|
23
|
+
initializeForwarderStatsUploader: () => AsyncUploader;
|
|
27
24
|
prepareForwardingStats: (
|
|
28
25
|
forwarder: MPForwarder,
|
|
29
26
|
event: IUploadObject
|
|
30
27
|
) => void;
|
|
31
28
|
}
|
|
32
29
|
|
|
30
|
+
export interface IForwardingStatsData {
|
|
31
|
+
mid: number; // Module Id
|
|
32
|
+
esid: number; // Event Subscription Id
|
|
33
|
+
n: string; // Event Name
|
|
34
|
+
attrs: ISDKUserAttributes; // User Attributes
|
|
35
|
+
sdk: string; // SDK Version
|
|
36
|
+
dt: number; // Data Type
|
|
37
|
+
et: number; // Event Type
|
|
38
|
+
dbg: boolean; // Development Mode (for debugging in Live Stream)
|
|
39
|
+
ct: number; // Current Timestamp
|
|
40
|
+
eec: number; // Expanded Event Count
|
|
41
|
+
dp: SDKDataPlan; // Data Plan
|
|
42
|
+
}
|
|
43
|
+
|
|
33
44
|
export default function APIClient(
|
|
34
45
|
this: IAPIClient,
|
|
35
46
|
mpInstance: MParticleWebSDK,
|
|
@@ -161,41 +172,26 @@ export default function APIClient(
|
|
|
161
172
|
}
|
|
162
173
|
};
|
|
163
174
|
|
|
164
|
-
this.
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
if (xhr.readyState === 4) {
|
|
170
|
-
if (xhr.status === 202) {
|
|
171
|
-
mpInstance.Logger.verbose(
|
|
172
|
-
'Successfully sent ' +
|
|
173
|
-
xhr.statusText +
|
|
174
|
-
' from server'
|
|
175
|
-
);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
const xhr = mpInstance._Helpers.createXHR(xhrCallback);
|
|
180
|
-
url = mpInstance._Helpers.createServiceUrl(
|
|
181
|
-
mpInstance._Store.SDKConfig.v1SecureServiceUrl,
|
|
182
|
-
mpInstance._Store.devToken
|
|
183
|
-
);
|
|
184
|
-
data = forwardingStatsData;
|
|
175
|
+
this.initializeForwarderStatsUploader = (): AsyncUploader => {
|
|
176
|
+
const {
|
|
177
|
+
v1SecureServiceUrl: forwardingDomain,
|
|
178
|
+
} = mpInstance._Store.SDKConfig;
|
|
179
|
+
const { devToken } = mpInstance._Store;
|
|
185
180
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
);
|
|
194
|
-
}
|
|
181
|
+
const uploadUrl: string = `https://${forwardingDomain}${devToken}/Forwarding`;
|
|
182
|
+
|
|
183
|
+
const uploader: AsyncUploader = window.fetch
|
|
184
|
+
? new FetchUploader(uploadUrl)
|
|
185
|
+
: new XHRUploader(uploadUrl);
|
|
186
|
+
|
|
187
|
+
return uploader;
|
|
195
188
|
};
|
|
196
189
|
|
|
197
|
-
this.prepareForwardingStats = function(
|
|
198
|
-
|
|
190
|
+
this.prepareForwardingStats = function(
|
|
191
|
+
forwarder: MPForwarder,
|
|
192
|
+
event:SDKEvent,
|
|
193
|
+
) : void {
|
|
194
|
+
let forwardingStatsData: IForwardingStatsData;
|
|
199
195
|
const queue = mpInstance._Forwarders.getForwarderStatsQueue();
|
|
200
196
|
|
|
201
197
|
if (forwarder && forwarder.isVisible) {
|
|
@@ -212,6 +208,11 @@ export default function APIClient(
|
|
|
212
208
|
eec: event.ExpandedEventCount,
|
|
213
209
|
dp: event.DataPlan,
|
|
214
210
|
};
|
|
211
|
+
|
|
212
|
+
const {
|
|
213
|
+
sendSingleForwardingStatsToServer,
|
|
214
|
+
setForwarderStatsQueue,
|
|
215
|
+
} = mpInstance._Forwarders;
|
|
215
216
|
|
|
216
217
|
if (
|
|
217
218
|
mpInstance._Helpers.getFeatureFlag(
|
|
@@ -219,9 +220,9 @@ export default function APIClient(
|
|
|
219
220
|
)
|
|
220
221
|
) {
|
|
221
222
|
queue.push(forwardingStatsData);
|
|
222
|
-
|
|
223
|
+
setForwarderStatsQueue(queue);
|
|
223
224
|
} else {
|
|
224
|
-
|
|
225
|
+
sendSingleForwardingStatsToServer(forwardingStatsData);
|
|
225
226
|
}
|
|
226
227
|
}
|
|
227
228
|
};
|
package/src/forwarders.js
CHANGED
|
@@ -3,11 +3,16 @@ import filteredMparticleUser from './filteredMparticleUser';
|
|
|
3
3
|
import { isEmpty } from './utils';
|
|
4
4
|
import KitFilterHelper from './kitFilterHelper';
|
|
5
5
|
import Constants from './constants';
|
|
6
|
+
import APIClient from './apiClient';
|
|
6
7
|
|
|
7
8
|
const { Modify, Identify, Login, Logout } = Constants.IdentityMethods;
|
|
8
9
|
|
|
9
10
|
export default function Forwarders(mpInstance, kitBlocker) {
|
|
10
11
|
var self = this;
|
|
12
|
+
this.forwarderStatsUploader = new APIClient(
|
|
13
|
+
mpInstance,
|
|
14
|
+
kitBlocker
|
|
15
|
+
).initializeForwarderStatsUploader();
|
|
11
16
|
|
|
12
17
|
const UserAttributeActionTypes = {
|
|
13
18
|
setUserAttribute: 'setUserAttribute',
|
|
@@ -771,4 +776,31 @@ export default function Forwarders(mpInstance, kitBlocker) {
|
|
|
771
776
|
);
|
|
772
777
|
}
|
|
773
778
|
};
|
|
779
|
+
|
|
780
|
+
this.sendSingleForwardingStatsToServer = async forwardingStatsData => {
|
|
781
|
+
// https://go.mparticle.com/work/SQDSDKS-6568
|
|
782
|
+
const fetchPayload = {
|
|
783
|
+
method: 'post',
|
|
784
|
+
body: JSON.stringify(forwardingStatsData),
|
|
785
|
+
headers: {
|
|
786
|
+
Accept: 'text/plain;charset=UTF-8',
|
|
787
|
+
'Content-Type': 'text/plain;charset=UTF-8',
|
|
788
|
+
},
|
|
789
|
+
};
|
|
790
|
+
|
|
791
|
+
const response = await this.forwarderStatsUploader.upload(fetchPayload);
|
|
792
|
+
|
|
793
|
+
let message;
|
|
794
|
+
// This is a fire and forget, so we only need to log the response based on the code, and not return any response body
|
|
795
|
+
if (response.status === 202) {
|
|
796
|
+
// https://go.mparticle.com/work/SQDSDKS-6670
|
|
797
|
+
message = 'Successfully sent forwarding stats to mParticle Servers';
|
|
798
|
+
} else {
|
|
799
|
+
message =
|
|
800
|
+
'Issue with forwarding stats to mParticle Servers, received HTTP Code of ' +
|
|
801
|
+
response.statusText;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
mpInstance?.Logger?.verbose(message);
|
|
805
|
+
};
|
|
774
806
|
}
|
|
@@ -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,
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
Product,
|
|
6
6
|
UserIdentities,
|
|
7
7
|
} from '@mparticle/web-sdk';
|
|
8
|
-
import {
|
|
8
|
+
import { IForwardingStatsData } from './apiClient';
|
|
9
9
|
import {
|
|
10
10
|
IntegrationAttributes,
|
|
11
11
|
ServerSettings,
|
|
@@ -18,7 +18,7 @@ import { UserAttributes } from './identity-user-interfaces';
|
|
|
18
18
|
export type UploadsTable = Dictionary<any>;
|
|
19
19
|
export interface iForwardingStatsBatches {
|
|
20
20
|
uploadsTable: UploadsTable;
|
|
21
|
-
forwardingStatsEventQueue:
|
|
21
|
+
forwardingStatsEventQueue: IForwardingStatsData[];
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
export interface IGlobalStoreV2MinifiedKeys {
|
package/src/sdkRuntimeModels.ts
CHANGED
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
|
|