@croct/sdk 0.14.0 → 0.15.1
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/activeRecord.js.map +1 -1
- package/apiKey.d.ts +18 -0
- package/apiKey.js +89 -0
- package/apiKey.js.map +1 -0
- package/cache/cache.d.ts +3 -0
- package/cache/cache.js +9 -0
- package/cache/cache.js.map +1 -1
- package/cache/cookieCache.d.ts +19 -0
- package/cache/cookieCache.js +54 -0
- package/cache/cookieCache.js.map +1 -0
- package/cache/fallbackCache.js.map +1 -1
- package/cache/localStorageCache.js.map +1 -1
- package/channel/beaconSocketChannel.js.map +1 -1
- package/channel/guaranteedChannel.js.map +1 -1
- package/channel/queuedChannel.js.map +1 -1
- package/channel/retryChannel.js.map +1 -1
- package/channel/sandboxChannel.js.map +1 -1
- package/channel/socketChannel.js.map +1 -1
- package/cid/cachedAssigner.js.map +1 -1
- package/cid/remoteAssigner.js.map +1 -1
- package/constants.d.ts +2 -2
- package/constants.js +1 -1
- package/container.d.ts +8 -1
- package/container.js +19 -7
- package/container.js.map +1 -1
- package/contentFetcher.d.ts +2 -1
- package/contentFetcher.js +8 -2
- package/contentFetcher.js.map +1 -1
- package/context.d.ts +4 -4
- package/context.js +4 -1
- package/context.js.map +1 -1
- package/error.js.map +1 -1
- package/evaluator.d.ts +2 -1
- package/evaluator.js +9 -3
- package/evaluator.js.map +1 -1
- package/eventManager.js.map +1 -1
- package/eventSubjectProcessor.d.ts +9 -0
- package/eventSubjectProcessor.js +67 -0
- package/eventSubjectProcessor.js.map +1 -0
- package/facade/contentFetcherFacade.d.ts +6 -1
- package/facade/contentFetcherFacade.js +5 -2
- package/facade/contentFetcherFacade.js.map +1 -1
- package/facade/evaluatorFacade.js.map +1 -1
- package/facade/sdkFacade.d.ts +11 -1
- package/facade/sdkFacade.js +9 -3
- package/facade/sdkFacade.js.map +1 -1
- package/facade/sessionPatch.js.map +1 -1
- package/facade/trackerFacade.js.map +1 -1
- package/facade/userPatch.js.map +1 -1
- package/logging/consoleLogger.js.map +1 -1
- package/namespacedStorage.js.map +1 -1
- package/package.json +4 -3
- package/queue/capacityRestrictedQueue.js.map +1 -1
- package/queue/inMemoryQueue.js.map +1 -1
- package/queue/monitoredQueue.js.map +1 -1
- package/queue/persistentQueue.js.map +1 -1
- package/retry/arbitraryPolicy.js.map +1 -1
- package/retry/backoffPolicy.js.map +1 -1
- package/retry/maxAttemptsPolicy.js.map +1 -1
- package/schema/sdkFacadeSchemas.js +9 -0
- package/schema/sdkFacadeSchemas.js.map +1 -1
- package/schema/sdkSchemas.d.ts +1 -0
- package/schema/sdkSchemas.js +30 -1
- package/schema/sdkSchemas.js.map +1 -1
- package/sdk.d.ts +8 -1
- package/sdk.js +1 -2
- package/sdk.js.map +1 -1
- package/sourceLocation.js.map +1 -1
- package/src/apiKey.ts +110 -0
- package/src/cache/cache.ts +7 -0
- package/src/cache/cookieCache.ts +77 -0
- package/src/container.ts +22 -5
- package/src/contentFetcher.ts +16 -5
- package/src/context.ts +7 -5
- package/src/evaluator.ts +16 -5
- package/src/eventSubjectProcessor.ts +85 -0
- package/src/facade/contentFetcherFacade.ts +11 -2
- package/src/facade/sdkFacade.ts +21 -3
- package/src/schema/sdkFacadeSchemas.ts +10 -1
- package/src/schema/sdkSchemas.ts +30 -0
- package/src/sdk.ts +8 -4
- package/src/token/token.ts +100 -18
- package/src/tracker.ts +59 -15
- package/tab.js.map +1 -1
- package/token/cachedTokenStore.js.map +1 -1
- package/token/token.d.ts +19 -2
- package/token/token.js +79 -16
- package/token/token.js.map +1 -1
- package/tracker.d.ts +9 -1
- package/tracker.js +37 -12
- package/tracker.js.map +1 -1
- package/uuid.js.map +1 -1
- package/validation/arrayType.js.map +1 -1
- package/validation/booleanType.js.map +1 -1
- package/validation/functionType.js.map +1 -1
- package/validation/jsonType.js.map +1 -1
- package/validation/nullType.js.map +1 -1
- package/validation/numberType.js.map +1 -1
- package/validation/objectType.js.map +1 -1
- package/validation/stringType.js.map +1 -1
- package/validation/unionType.js.map +1 -1
- package/validation/violation.js.map +1 -1
- package/base64Url.d.ts +0 -2
- package/base64Url.js +0 -28
- package/base64Url.js.map +0 -1
- package/src/base64Url.ts +0 -36
|
@@ -34,6 +34,15 @@ exports.sdkFacadeConfigurationSchema = new validation_1.ObjectType({
|
|
|
34
34
|
cidAssignerEndpointUrl: new validation_1.StringType({
|
|
35
35
|
format: 'url',
|
|
36
36
|
}),
|
|
37
|
+
cookie: new validation_1.ObjectType({
|
|
38
|
+
properties: {
|
|
39
|
+
clientId: sdkSchemas_1.cookieOptionsSchema,
|
|
40
|
+
userToken: sdkSchemas_1.cookieOptionsSchema,
|
|
41
|
+
},
|
|
42
|
+
}),
|
|
43
|
+
preferredLocale: new validation_1.StringType({
|
|
44
|
+
pattern: /^[a-z]{2,3}([-_][a-z]{2,3})?$/i,
|
|
45
|
+
}),
|
|
37
46
|
},
|
|
38
47
|
});
|
|
39
48
|
//# sourceMappingURL=sdkFacadeSchemas.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdkFacadeSchemas.js","sourceRoot":"","sources":["../src/schema/sdkFacadeSchemas.ts"],"names":[],"mappings":";;;AAAA,8CAAqG;AACrG,qDAAkD;AAClD,
|
|
1
|
+
{"version":3,"file":"sdkFacadeSchemas.js","sourceRoot":"","sources":["../src/schema/sdkFacadeSchemas.ts"],"names":[],"mappings":";;;AAAA,8CAAqG;AACrG,qDAAkD;AAClD,6CAAsE;AACtE,iDAA4C;AAE/B,QAAA,4BAA4B,GAAG,IAAI,uBAAU,CAAC;IACvD,QAAQ,EAAE,CAAC,OAAO,CAAC;IACnB,UAAU,EAAE;QACR,KAAK,EAAE,IAAI,uBAAU,CAAC;YAClB,MAAM,EAAE,MAAM;SACjB,CAAC;QACF,QAAQ,EAAE,IAAI,uBAAU,CAAC;YACrB,OAAO,EAAE,iBAAiB;SAC7B,CAAC;QACF,UAAU,EAAE,iCAAgB;QAC5B,mBAAmB,EAAE,IAAI,wBAAW,EAAE;QACtC,KAAK,EAAE,IAAI,wBAAW,EAAE;QACxB,IAAI,EAAE,IAAI,wBAAW,EAAE;QACvB,KAAK,EAAE,IAAI,wBAAW,EAAE;QACxB,MAAM,EAAE,2BAAY;QACpB,YAAY,EAAE,IAAI,yBAAY,EAAE;QAChC,aAAa,EAAE,gCAAmB;QAClC,MAAM,EAAE,IAAI,sBAAS,CACjB,IAAI,uBAAU,CAAC;YACX,SAAS,EAAE,CAAC;SACf,CAAC,EACF,IAAI,qBAAQ,EAAE,CACjB;QACD,KAAK,EAAE,IAAI,sBAAS,CAChB,IAAI,uBAAU,CAAC;YACX,OAAO,EAAE,yDAAyD;SACrE,CAAC,EACF,IAAI,qBAAQ,EAAE,CACjB;QACD,eAAe,EAAE,IAAI,uBAAU,CAAC;YAC5B,MAAM,EAAE,KAAK;SAChB,CAAC;QACF,sBAAsB,EAAE,IAAI,uBAAU,CAAC;YACnC,MAAM,EAAE,KAAK;SAChB,CAAC;QACF,MAAM,EAAE,IAAI,uBAAU,CAAC;YACnB,UAAU,EAAE;gBACR,QAAQ,EAAE,gCAAmB;gBAC7B,SAAS,EAAE,gCAAmB;aACjC;SACJ,CAAC;QACF,eAAe,EAAE,IAAI,uBAAU,CAAC;YAC5B,OAAO,EAAE,gCAAgC;SAC5C,CAAC;KACL;CACJ,CAAC,CAAC"}
|
package/schema/sdkSchemas.d.ts
CHANGED
package/schema/sdkSchemas.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.sdkConfigurationSchema = exports.eventMetadataSchema = void 0;
|
|
3
|
+
exports.sdkConfigurationSchema = exports.cookieOptionsSchema = exports.eventMetadataSchema = void 0;
|
|
4
4
|
const validation_1 = require("../validation");
|
|
5
5
|
const contextSchemas_1 = require("./contextSchemas");
|
|
6
6
|
const loggerSchema_1 = require("./loggerSchema");
|
|
@@ -15,6 +15,28 @@ exports.eventMetadataSchema = new validation_1.ObjectType({
|
|
|
15
15
|
maxLength: 300,
|
|
16
16
|
}),
|
|
17
17
|
});
|
|
18
|
+
exports.cookieOptionsSchema = new validation_1.ObjectType({
|
|
19
|
+
required: ['name'],
|
|
20
|
+
properties: {
|
|
21
|
+
name: new validation_1.StringType({
|
|
22
|
+
minLength: 1,
|
|
23
|
+
}),
|
|
24
|
+
domain: new validation_1.StringType({
|
|
25
|
+
minLength: 1,
|
|
26
|
+
}),
|
|
27
|
+
path: new validation_1.StringType({
|
|
28
|
+
minLength: 1,
|
|
29
|
+
}),
|
|
30
|
+
secure: new validation_1.BooleanType(),
|
|
31
|
+
sameSite: new validation_1.StringType({
|
|
32
|
+
enumeration: ['strict', 'lax', 'none'],
|
|
33
|
+
}),
|
|
34
|
+
maxAge: new validation_1.NumberType({
|
|
35
|
+
minimum: 0,
|
|
36
|
+
integer: true,
|
|
37
|
+
}),
|
|
38
|
+
},
|
|
39
|
+
});
|
|
18
40
|
exports.sdkConfigurationSchema = new validation_1.ObjectType({
|
|
19
41
|
required: ['appId', 'tokenScope', 'disableCidMirroring', 'debug', 'test'],
|
|
20
42
|
properties: {
|
|
@@ -36,11 +58,18 @@ exports.sdkConfigurationSchema = new validation_1.ObjectType({
|
|
|
36
58
|
integer: true,
|
|
37
59
|
}),
|
|
38
60
|
disableCidMirroring: new validation_1.BooleanType(),
|
|
61
|
+
cookie: new validation_1.ObjectType({
|
|
62
|
+
properties: {
|
|
63
|
+
clientId: exports.cookieOptionsSchema,
|
|
64
|
+
userToken: exports.cookieOptionsSchema,
|
|
65
|
+
},
|
|
66
|
+
}),
|
|
39
67
|
debug: new validation_1.BooleanType(),
|
|
40
68
|
test: new validation_1.BooleanType(),
|
|
41
69
|
logger: loggerSchema_1.loggerSchema,
|
|
42
70
|
urlSanitizer: new validation_1.FunctionType(),
|
|
43
71
|
eventMetadata: exports.eventMetadataSchema,
|
|
72
|
+
eventProcessor: new validation_1.FunctionType(),
|
|
44
73
|
},
|
|
45
74
|
});
|
|
46
75
|
//# sourceMappingURL=sdkSchemas.js.map
|
package/schema/sdkSchemas.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdkSchemas.js","sourceRoot":"","sources":["../src/schema/sdkSchemas.ts"],"names":[],"mappings":";;;AAAA,8CAA4F;AAC5F,qDAAkD;AAClD,iDAA4C;AAE/B,QAAA,mBAAmB,GAAG,IAAI,uBAAU,CAAC;IAC9C,aAAa,EAAE,CAAC;IAChB,aAAa,EAAE,IAAI,uBAAU,CAAC;QAC1B,SAAS,EAAE,CAAC;QACZ,SAAS,EAAE,EAAE;QACb,MAAM,EAAE,YAAY;KACvB,CAAC;IACF,oBAAoB,EAAE,IAAI,uBAAU,CAAC;QACjC,SAAS,EAAE,GAAG;KACjB,CAAC;CACL,CAAC,CAAC;AAEU,QAAA,sBAAsB,GAAG,IAAI,uBAAU,CAAC;IACjD,QAAQ,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,CAAC;IACzE,UAAU,EAAE;QACR,KAAK,EAAE,IAAI,uBAAU,CAAC;YAClB,MAAM,EAAE,MAAM;SACjB,CAAC;QACF,QAAQ,EAAE,IAAI,uBAAU,CAAC;YACrB,OAAO,EAAE,iBAAiB;SAC7B,CAAC;QACF,UAAU,EAAE,iCAAgB;QAC5B,eAAe,EAAE,IAAI,uBAAU,CAAC;YAC5B,MAAM,EAAE,KAAK;SAChB,CAAC;QACF,sBAAsB,EAAE,IAAI,uBAAU,CAAC;YACnC,MAAM,EAAE,KAAK;SAChB,CAAC;QACF,eAAe,EAAE,IAAI,uBAAU,CAAC;YAC5B,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,IAAI;SAChB,CAAC;QACF,mBAAmB,EAAE,IAAI,wBAAW,EAAE;QACtC,KAAK,EAAE,IAAI,wBAAW,EAAE;QACxB,IAAI,EAAE,IAAI,wBAAW,EAAE;QACvB,MAAM,EAAE,2BAAY;QACpB,YAAY,EAAE,IAAI,yBAAY,EAAE;QAChC,aAAa,EAAE,2BAAmB;KACrC;CACJ,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"sdkSchemas.js","sourceRoot":"","sources":["../src/schema/sdkSchemas.ts"],"names":[],"mappings":";;;AAAA,8CAA4F;AAC5F,qDAAkD;AAClD,iDAA4C;AAE/B,QAAA,mBAAmB,GAAG,IAAI,uBAAU,CAAC;IAC9C,aAAa,EAAE,CAAC;IAChB,aAAa,EAAE,IAAI,uBAAU,CAAC;QAC1B,SAAS,EAAE,CAAC;QACZ,SAAS,EAAE,EAAE;QACb,MAAM,EAAE,YAAY;KACvB,CAAC;IACF,oBAAoB,EAAE,IAAI,uBAAU,CAAC;QACjC,SAAS,EAAE,GAAG;KACjB,CAAC;CACL,CAAC,CAAC;AAEU,QAAA,mBAAmB,GAAG,IAAI,uBAAU,CAAC;IAC9C,QAAQ,EAAE,CAAC,MAAM,CAAC;IAClB,UAAU,EAAE;QACR,IAAI,EAAE,IAAI,uBAAU,CAAC;YACjB,SAAS,EAAE,CAAC;SACf,CAAC;QACF,MAAM,EAAE,IAAI,uBAAU,CAAC;YACnB,SAAS,EAAE,CAAC;SACf,CAAC;QACF,IAAI,EAAE,IAAI,uBAAU,CAAC;YACjB,SAAS,EAAE,CAAC;SACf,CAAC;QACF,MAAM,EAAE,IAAI,wBAAW,EAAE;QACzB,QAAQ,EAAE,IAAI,uBAAU,CAAC;YACrB,WAAW,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC;SACzC,CAAC;QACF,MAAM,EAAE,IAAI,uBAAU,CAAC;YACnB,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,IAAI;SAChB,CAAC;KACL;CACJ,CAAC,CAAC;AAEU,QAAA,sBAAsB,GAAG,IAAI,uBAAU,CAAC;IACjD,QAAQ,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,CAAC;IACzE,UAAU,EAAE;QACR,KAAK,EAAE,IAAI,uBAAU,CAAC;YAClB,MAAM,EAAE,MAAM;SACjB,CAAC;QACF,QAAQ,EAAE,IAAI,uBAAU,CAAC;YACrB,OAAO,EAAE,iBAAiB;SAC7B,CAAC;QACF,UAAU,EAAE,iCAAgB;QAC5B,eAAe,EAAE,IAAI,uBAAU,CAAC;YAC5B,MAAM,EAAE,KAAK;SAChB,CAAC;QACF,sBAAsB,EAAE,IAAI,uBAAU,CAAC;YACnC,MAAM,EAAE,KAAK;SAChB,CAAC;QACF,eAAe,EAAE,IAAI,uBAAU,CAAC;YAC5B,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,IAAI;SAChB,CAAC;QACF,mBAAmB,EAAE,IAAI,wBAAW,EAAE;QACtC,MAAM,EAAE,IAAI,uBAAU,CAAC;YACnB,UAAU,EAAE;gBACR,QAAQ,EAAE,2BAAmB;gBAC7B,SAAS,EAAE,2BAAmB;aACjC;SACJ,CAAC;QACF,KAAK,EAAE,IAAI,wBAAW,EAAE;QACxB,IAAI,EAAE,IAAI,wBAAW,EAAE;QACvB,MAAM,EAAE,2BAAY;QACpB,YAAY,EAAE,IAAI,yBAAY,EAAE;QAChC,aAAa,EAAE,2BAAmB;QAClC,cAAc,EAAE,IAAI,yBAAY,EAAE;KACrC;CACJ,CAAC,CAAC"}
|
package/sdk.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { DependencyResolver } from './container';
|
|
1
2
|
import { Context, TokenScope } from './context';
|
|
2
3
|
import { Logger } from './logging';
|
|
3
|
-
import { Tracker } from './tracker';
|
|
4
|
+
import { Tracker, TrackingEventProcessor } from './tracker';
|
|
4
5
|
import { Evaluator } from './evaluator';
|
|
5
6
|
import { SdkEventMap } from './sdkEvents';
|
|
6
7
|
import { EventManager } from './eventManager';
|
|
@@ -8,6 +9,7 @@ import { CidAssigner } from './cid';
|
|
|
8
9
|
import { UrlSanitizer } from './tab';
|
|
9
10
|
import { ContentFetcher } from './contentFetcher';
|
|
10
11
|
import { TokenStore } from './token';
|
|
12
|
+
import { CookieCacheConfiguration } from './cache/cookieCache';
|
|
11
13
|
export type Configuration = {
|
|
12
14
|
appId: string;
|
|
13
15
|
tokenScope: TokenScope;
|
|
@@ -23,6 +25,11 @@ export type Configuration = {
|
|
|
23
25
|
eventMetadata?: {
|
|
24
26
|
[key: string]: string;
|
|
25
27
|
};
|
|
28
|
+
cookie?: {
|
|
29
|
+
clientId?: CookieCacheConfiguration;
|
|
30
|
+
userToken?: CookieCacheConfiguration;
|
|
31
|
+
};
|
|
32
|
+
eventProcessor?: DependencyResolver<TrackingEventProcessor>;
|
|
26
33
|
};
|
|
27
34
|
export declare class Sdk {
|
|
28
35
|
private container;
|
package/sdk.js
CHANGED
|
@@ -23,7 +23,7 @@ class Sdk {
|
|
|
23
23
|
static init(configuration) {
|
|
24
24
|
var _a;
|
|
25
25
|
validateConfiguration(configuration);
|
|
26
|
-
const {
|
|
26
|
+
const { eventMetadata: customMetadata = {}, baseEndpointUrl = constants_1.BASE_ENDPOINT_URL, cidAssignerEndpointUrl, ...containerConfiguration } = configuration;
|
|
27
27
|
const eventMetadata = {
|
|
28
28
|
sdkVersion: constants_1.VERSION,
|
|
29
29
|
};
|
|
@@ -34,7 +34,6 @@ class Sdk {
|
|
|
34
34
|
const baseWsEndpoint = baseHttpEndpoint.replace(/^http/i, 'ws');
|
|
35
35
|
const container = new container_1.Container({
|
|
36
36
|
...containerConfiguration,
|
|
37
|
-
disableCidMirroring: disableCidMirroring,
|
|
38
37
|
evaluationBaseEndpointUrl: baseHttpEndpoint,
|
|
39
38
|
contentBaseEndpointUrl: baseHttpEndpoint,
|
|
40
39
|
trackerEndpointUrl: `${baseWsEndpoint}/client/web/connect`,
|
package/sdk.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.js","sourceRoot":"","sources":["src/sdk.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"sdk.js","sourceRoot":"","sources":["src/sdk.ts"],"names":[],"mappings":"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"}
|
package/sourceLocation.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sourceLocation.js","sourceRoot":"","sources":["src/sourceLocation.ts"],"names":[],"mappings":";;;AAWA,SAAgB,SAAS,CAAC,KAAa;IACnC,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC;AAC7B,CAAC;AAFD,8BAEC;AAED,SAAgB,WAAW,CAAC,KAAa,EAAE,UAAkB,EAAE,QAAgB;IAC3E,IAAI,UAAU,GAAG,CAAC,EAAE;
|
|
1
|
+
{"version":3,"file":"sourceLocation.js","sourceRoot":"","sources":["src/sourceLocation.ts"],"names":[],"mappings":";;;AAWA,SAAgB,SAAS,CAAC,KAAa;IACnC,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC;AAC7B,CAAC;AAFD,8BAEC;AAED,SAAgB,WAAW,CAAC,KAAa,EAAE,UAAkB,EAAE,QAAgB;IAC3E,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;QACjB,MAAM,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACvD,CAAC;IAED,IAAI,QAAQ,GAAG,UAAU,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;IACpF,CAAC;IAED,IAAI,KAA2B,CAAC;IAChC,IAAI,GAAyB,CAAC;IAE9B,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;IACzB,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;QACnD,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;QAE3B,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;YACxB,KAAK,GAAG;gBACJ,KAAK,EAAE,MAAM;gBACb,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE,MAAM;aACjB,CAAC;QACN,CAAC;QAED,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YACtB,GAAG,GAAG;gBACF,KAAK,EAAE,MAAM;gBACb,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE,MAAM;aACjB,CAAC;YAEF,MAAM;QACV,CAAC;QAED,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAChB,IAAI,IAAI,CAAC,CAAC;YACV,MAAM,GAAG,CAAC,CAAC;QACf,CAAC;aAAM,CAAC;YACJ,MAAM,IAAI,CAAC,CAAC;QAChB,CAAC;IACL,CAAC;IAED,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACtB,KAAK,GAAG;YACJ,KAAK,EAAE,KAAK,CAAC,MAAM;YACnB,IAAI,EAAE,IAAI;YACV,MAAM,EAAE,MAAM;SACjB,CAAC;IACN,CAAC;IAED,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACpB,GAAG,GAAG;YACF,KAAK,EAAE,KAAK,CAAC,MAAM;YACnB,IAAI,EAAE,IAAI;YACV,MAAM,EAAE,MAAM;SACjB,CAAC;IACN,CAAC;IAED,OAAO;QACH,KAAK,EAAE,KAAK;QACZ,GAAG,EAAE,GAAG;KACX,CAAC;AACN,CAAC;AAjED,kCAiEC;AAED,SAAgB,WAAW,CAAC,KAAa,EAAE,KAAa;IACpD,OAAO,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC;AAClD,CAAC;AAFD,kCAEC"}
|
package/src/apiKey.ts
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import * as crypto from 'crypto';
|
|
2
|
+
import {KeyObject} from 'crypto';
|
|
3
|
+
|
|
4
|
+
export class ApiKey {
|
|
5
|
+
private static readonly IDENTIFIER_PATTERN = /^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$/i;
|
|
6
|
+
|
|
7
|
+
private static readonly PRIVATE_KEY_PATTERN = /^[a-f0-9]+$/i;
|
|
8
|
+
|
|
9
|
+
private readonly identifier: string;
|
|
10
|
+
|
|
11
|
+
private readonly privateKey?: KeyObject;
|
|
12
|
+
|
|
13
|
+
private constructor(identifier: string, privateKey?: KeyObject) {
|
|
14
|
+
this.identifier = identifier;
|
|
15
|
+
this.privateKey = privateKey;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public static from(apiKey: string | ApiKey): ApiKey {
|
|
19
|
+
if (apiKey instanceof ApiKey) {
|
|
20
|
+
return apiKey;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return ApiKey.parse(apiKey);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public static parse(apiKey: string): ApiKey {
|
|
27
|
+
const parts = apiKey.split(':');
|
|
28
|
+
|
|
29
|
+
if (parts.length > 2) {
|
|
30
|
+
throw new Error('Invalid API key format.');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return ApiKey.of(parts[0], parts[1]);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public static of(identifier: string, privateKey?: string): ApiKey {
|
|
37
|
+
if (!ApiKey.IDENTIFIER_PATTERN.test(identifier)) {
|
|
38
|
+
throw new Error('The API key identifier must be a UUID.');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (privateKey === undefined) {
|
|
42
|
+
return new ApiKey(identifier);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (!ApiKey.PRIVATE_KEY_PATTERN.test(privateKey)) {
|
|
46
|
+
throw new Error('The API key private key must be a hexadecimal string.');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
return new ApiKey(identifier, crypto.createPrivateKey({
|
|
51
|
+
key: Buffer.from(privateKey, 'hex'),
|
|
52
|
+
format: 'der',
|
|
53
|
+
type: 'pkcs8',
|
|
54
|
+
}));
|
|
55
|
+
} catch {
|
|
56
|
+
throw new Error('Invalid private key.');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public getIdentifier(): string {
|
|
61
|
+
return this.identifier;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public async getIdentifierHash(): Promise<string> {
|
|
65
|
+
const identifierBytes = Buffer.from(this.identifier.replace(/-/g, ''), 'hex');
|
|
66
|
+
const rawHash = await crypto.subtle.digest('SHA-256', identifierBytes);
|
|
67
|
+
|
|
68
|
+
return Buffer.from(rawHash).toString('hex');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
public hasPrivateKey(): boolean {
|
|
72
|
+
return this.privateKey !== undefined;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public getPrivateKey(): string|null {
|
|
76
|
+
return this.privateKey === undefined
|
|
77
|
+
? null
|
|
78
|
+
: this.privateKey
|
|
79
|
+
.export({format: 'der', type: 'pkcs8'})
|
|
80
|
+
.toString('hex');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public sign(blob: Buffer): Promise<Buffer> {
|
|
84
|
+
const {privateKey} = this;
|
|
85
|
+
|
|
86
|
+
if (privateKey === undefined) {
|
|
87
|
+
return Promise.reject(new Error('The API key does not have a private key.'));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return new Promise((resolve, reject) => {
|
|
91
|
+
crypto.sign(null, blob, privateKey, (error, signature) => {
|
|
92
|
+
if (error == null) {
|
|
93
|
+
resolve(signature);
|
|
94
|
+
} else {
|
|
95
|
+
reject(error);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public export(): string {
|
|
102
|
+
const privateKey = this.getPrivateKey();
|
|
103
|
+
|
|
104
|
+
return this.identifier + (privateKey === null ? '' : `:${privateKey}`);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
public toString(): string {
|
|
108
|
+
return '[redacted]';
|
|
109
|
+
}
|
|
110
|
+
}
|
package/src/cache/cache.ts
CHANGED
|
@@ -13,3 +13,10 @@ export interface ObservableCache extends Cache {
|
|
|
13
13
|
|
|
14
14
|
removeListener(listener: CacheListener): void;
|
|
15
15
|
}
|
|
16
|
+
|
|
17
|
+
export namespace ObservableCache {
|
|
18
|
+
export function isObservable(cache: Cache): cache is ObservableCache {
|
|
19
|
+
return typeof (cache as ObservableCache).addListener === 'function'
|
|
20
|
+
&& typeof (cache as ObservableCache).removeListener === 'function';
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import {Cache} from './cache';
|
|
2
|
+
|
|
3
|
+
export type CookieCacheConfiguration = {
|
|
4
|
+
name: string,
|
|
5
|
+
secure?: boolean,
|
|
6
|
+
maxAge?: number,
|
|
7
|
+
domain?: string,
|
|
8
|
+
path?: string,
|
|
9
|
+
sameSite?: 'strict' | 'lax' | 'none',
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export class CookieCache implements Cache {
|
|
13
|
+
private readonly config: CookieCacheConfiguration;
|
|
14
|
+
|
|
15
|
+
public constructor(config: CookieCacheConfiguration) {
|
|
16
|
+
this.config = config;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public get(): string | null {
|
|
20
|
+
const entries = document.cookie.split(';');
|
|
21
|
+
|
|
22
|
+
for (const entry of entries) {
|
|
23
|
+
const [name, value] = entry.split('=');
|
|
24
|
+
|
|
25
|
+
if (CookieCache.decode(name).trim() === this.config.name) {
|
|
26
|
+
return CookieCache.decode(value.trim());
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public put(value: string): void {
|
|
34
|
+
document.cookie = CookieCache.serializeCookie(value, this.config);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public clear(): void {
|
|
38
|
+
document.cookie = CookieCache.serializeCookie('', {
|
|
39
|
+
...this.config,
|
|
40
|
+
maxAge: 0,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private static serializeCookie(value: string, config: CookieCacheConfiguration): string {
|
|
45
|
+
const cookie = [`${CookieCache.encode(config.name)}=${CookieCache.encode(value)}`];
|
|
46
|
+
|
|
47
|
+
if (config.maxAge !== undefined) {
|
|
48
|
+
cookie.push(`Max-Age=${config.maxAge}`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (config.domain !== undefined) {
|
|
52
|
+
cookie.push(`Domain=${CookieCache.encode(config.domain)}`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (config.path !== undefined) {
|
|
56
|
+
cookie.push(`Path=${CookieCache.encode(config.path)}`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (config.secure === true) {
|
|
60
|
+
cookie.push('Secure');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (config.sameSite !== undefined) {
|
|
64
|
+
cookie.push(`SameSite=${({strict: 'Strict', lax: 'Lax', none: 'None'})[config.sameSite]}`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return cookie.join('; ');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private static encode(value: string): string {
|
|
71
|
+
return value.replace(/[,; ]+/g, encodeURIComponent);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
private static decode(value: string): string {
|
|
75
|
+
return decodeURIComponent(value);
|
|
76
|
+
}
|
|
77
|
+
}
|
package/src/container.ts
CHANGED
|
@@ -5,7 +5,7 @@ import {BackoffPolicy, ArbitraryPolicy} from './retry';
|
|
|
5
5
|
import {PersistentQueue, MonitoredQueue, CapacityRestrictedQueue} from './queue';
|
|
6
6
|
import {Beacon} from './trackingEvents';
|
|
7
7
|
import {CachedTokenStore, TokenStore} from './token';
|
|
8
|
-
import {Tracker} from './tracker';
|
|
8
|
+
import {Tracker, TrackingEventProcessor} from './tracker';
|
|
9
9
|
import {Evaluator} from './evaluator';
|
|
10
10
|
import {encodeJson} from './transformer';
|
|
11
11
|
import {CidAssigner, CachedAssigner, RemoteAssigner, FixedAssigner} from './cid';
|
|
@@ -25,6 +25,9 @@ import {
|
|
|
25
25
|
SandboxChannel,
|
|
26
26
|
} from './channel';
|
|
27
27
|
import {ContentFetcher} from './contentFetcher';
|
|
28
|
+
import {CookieCache, CookieCacheConfiguration} from './cache/cookieCache';
|
|
29
|
+
|
|
30
|
+
export type DependencyResolver<T> = (container: Container) => T;
|
|
28
31
|
|
|
29
32
|
export type Configuration = {
|
|
30
33
|
appId: string,
|
|
@@ -40,7 +43,12 @@ export type Configuration = {
|
|
|
40
43
|
beaconQueueSize: number,
|
|
41
44
|
logger?: Logger,
|
|
42
45
|
urlSanitizer?: UrlSanitizer,
|
|
46
|
+
cookie?: {
|
|
47
|
+
clientId?: CookieCacheConfiguration,
|
|
48
|
+
userToken?: CookieCacheConfiguration,
|
|
49
|
+
},
|
|
43
50
|
eventMetadata?: {[key: string]: string},
|
|
51
|
+
eventProcessor?: DependencyResolver<TrackingEventProcessor>,
|
|
44
52
|
};
|
|
45
53
|
|
|
46
54
|
export class Container {
|
|
@@ -136,6 +144,9 @@ export class Container {
|
|
|
136
144
|
logger: this.getLogger('Tracker'),
|
|
137
145
|
channel: this.getBeaconChannel(),
|
|
138
146
|
eventMetadata: this.configuration.eventMetadata,
|
|
147
|
+
processor: this.configuration.eventProcessor === undefined
|
|
148
|
+
? undefined
|
|
149
|
+
: this.configuration.eventProcessor(this),
|
|
139
150
|
});
|
|
140
151
|
|
|
141
152
|
const queue = this.getBeaconQueue();
|
|
@@ -170,11 +181,15 @@ export class Container {
|
|
|
170
181
|
private createContext(): Context {
|
|
171
182
|
const tokenKey = this.resolveStorageNamespace('token');
|
|
172
183
|
const tabKey = this.resolveStorageNamespace('tab');
|
|
173
|
-
const
|
|
174
|
-
|
|
184
|
+
const browserCache = this.configuration.tokenScope === 'global'
|
|
185
|
+
&& this.configuration.cookie?.userToken !== undefined
|
|
186
|
+
? new CookieCache(this.configuration.cookie.userToken)
|
|
187
|
+
: new LocalStorageCache(this.getLocalStorage(), tokenKey);
|
|
175
188
|
const tabStorage = this.getSessionStorage();
|
|
176
189
|
|
|
177
|
-
|
|
190
|
+
if (browserCache instanceof LocalStorageCache) {
|
|
191
|
+
this.removeTokenSyncListener = LocalStorageCache.autoSync(browserCache);
|
|
192
|
+
}
|
|
178
193
|
|
|
179
194
|
return Context.load({
|
|
180
195
|
tokenScope: this.configuration.tokenScope,
|
|
@@ -262,7 +277,9 @@ export class Container {
|
|
|
262
277
|
|
|
263
278
|
return new CachedAssigner(
|
|
264
279
|
new RemoteAssigner(this.configuration.cidAssignerEndpointUrl, logger),
|
|
265
|
-
|
|
280
|
+
this.configuration.cookie?.clientId !== undefined
|
|
281
|
+
? new CookieCache(this.configuration.cookie?.clientId)
|
|
282
|
+
: new LocalStorageCache(this.getLocalStorage(), 'croct.cid'),
|
|
266
283
|
{
|
|
267
284
|
logger: logger,
|
|
268
285
|
mirror: !this.configuration.disableCidMirroring,
|
package/src/contentFetcher.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {Token} from './token';
|
|
|
4
4
|
import {BASE_ENDPOINT_URL, CLIENT_LIBRARY} from './constants';
|
|
5
5
|
import {formatMessage} from './error';
|
|
6
6
|
import {Logger, NullLogger} from './logging';
|
|
7
|
+
import type {ApiKey} from './apiKey';
|
|
7
8
|
|
|
8
9
|
export type ErrorResponse = {
|
|
9
10
|
type: string,
|
|
@@ -76,13 +77,18 @@ export type FetchResponse<P extends JsonObject = JsonObject> = {
|
|
|
76
77
|
|
|
77
78
|
export type Configuration = {
|
|
78
79
|
appId?: string,
|
|
79
|
-
apiKey?: string,
|
|
80
|
+
apiKey?: string|ApiKey,
|
|
80
81
|
baseEndpointUrl?: string,
|
|
81
82
|
logger?: Logger,
|
|
82
83
|
};
|
|
83
84
|
|
|
85
|
+
type InternalConfiguration = {
|
|
86
|
+
appId?: string,
|
|
87
|
+
apiKey?: string,
|
|
88
|
+
};
|
|
89
|
+
|
|
84
90
|
export class ContentFetcher {
|
|
85
|
-
private readonly configuration:
|
|
91
|
+
private readonly configuration: InternalConfiguration;
|
|
86
92
|
|
|
87
93
|
private readonly dynamicEndpoint: string;
|
|
88
94
|
|
|
@@ -95,9 +101,10 @@ export class ContentFetcher {
|
|
|
95
101
|
throw new Error('Either the application ID or the API key must be provided.');
|
|
96
102
|
}
|
|
97
103
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
104
|
+
const {baseEndpointUrl} = configuration;
|
|
105
|
+
const apiKey = typeof configuration.apiKey === 'object'
|
|
106
|
+
? configuration.apiKey.getIdentifier()
|
|
107
|
+
: configuration.apiKey;
|
|
101
108
|
|
|
102
109
|
// eslint-disable-next-line prefer-template -- Better readability
|
|
103
110
|
const baseEndpoint = (baseEndpointUrl ?? BASE_ENDPOINT_URL).replace(/\/+$/, '')
|
|
@@ -107,6 +114,10 @@ export class ContentFetcher {
|
|
|
107
114
|
this.dynamicEndpoint = `${baseEndpoint}/content`;
|
|
108
115
|
this.staticEndpoint = `${baseEndpoint}/static-content`;
|
|
109
116
|
this.logger = configuration.logger ?? new NullLogger();
|
|
117
|
+
this.configuration = {
|
|
118
|
+
appId: configuration.appId,
|
|
119
|
+
apiKey: apiKey,
|
|
120
|
+
};
|
|
110
121
|
}
|
|
111
122
|
|
|
112
123
|
public fetch<P extends JsonObject>(slotId: string, options: FetchOptions = {}): Promise<FetchResponse<P>> {
|
package/src/context.ts
CHANGED
|
@@ -3,7 +3,7 @@ import {Tab, UrlSanitizer} from './tab';
|
|
|
3
3
|
import {uuid4} from './uuid';
|
|
4
4
|
import {EventDispatcher} from './eventManager';
|
|
5
5
|
import {SdkEventMap} from './sdkEvents';
|
|
6
|
-
import {
|
|
6
|
+
import {Cache, ObservableCache} from './cache';
|
|
7
7
|
|
|
8
8
|
export type TokenScope = 'isolated' | 'global' | 'contextual';
|
|
9
9
|
|
|
@@ -12,9 +12,9 @@ export type Configuration = {
|
|
|
12
12
|
urlSanitizer?: UrlSanitizer,
|
|
13
13
|
eventDispatcher: ContextEventDispatcher,
|
|
14
14
|
cache: {
|
|
15
|
-
tabId:
|
|
16
|
-
tabToken:
|
|
17
|
-
browserToken:
|
|
15
|
+
tabId: Cache,
|
|
16
|
+
tabToken: Cache,
|
|
17
|
+
browserToken: Cache,
|
|
18
18
|
},
|
|
19
19
|
};
|
|
20
20
|
|
|
@@ -63,7 +63,9 @@ export class Context {
|
|
|
63
63
|
case 'global': {
|
|
64
64
|
const context = new Context(tab, new CachedTokenStore(cache.browserToken), eventDispatcher);
|
|
65
65
|
|
|
66
|
-
cache.browserToken
|
|
66
|
+
if (ObservableCache.isObservable(cache.browserToken)) {
|
|
67
|
+
cache.browserToken.addListener(context.syncToken);
|
|
68
|
+
}
|
|
67
69
|
|
|
68
70
|
return context;
|
|
69
71
|
}
|
package/src/evaluator.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {BASE_ENDPOINT_URL, CLIENT_LIBRARY, MAX_QUERY_LENGTH} from './constants';
|
|
|
4
4
|
import {formatMessage} from './error';
|
|
5
5
|
import {getLength, getLocation, Location} from './sourceLocation';
|
|
6
6
|
import {Logger, NullLogger} from './logging';
|
|
7
|
+
import type {ApiKey} from './apiKey';
|
|
7
8
|
|
|
8
9
|
export type Campaign = {
|
|
9
10
|
name?: string,
|
|
@@ -94,15 +95,20 @@ export class QueryError extends EvaluationError<QueryErrorResponse> {
|
|
|
94
95
|
|
|
95
96
|
export type Configuration = {
|
|
96
97
|
appId?: string,
|
|
97
|
-
apiKey?: string,
|
|
98
|
+
apiKey?: string|ApiKey,
|
|
98
99
|
baseEndpointUrl?: string,
|
|
99
100
|
logger?: Logger,
|
|
100
101
|
};
|
|
101
102
|
|
|
103
|
+
type InternalConfiguration = {
|
|
104
|
+
appId?: string,
|
|
105
|
+
apiKey?: string,
|
|
106
|
+
};
|
|
107
|
+
|
|
102
108
|
export class Evaluator {
|
|
103
109
|
public static readonly MAX_QUERY_LENGTH = MAX_QUERY_LENGTH;
|
|
104
110
|
|
|
105
|
-
private readonly configuration:
|
|
111
|
+
private readonly configuration: InternalConfiguration;
|
|
106
112
|
|
|
107
113
|
private readonly endpoint: string;
|
|
108
114
|
|
|
@@ -113,15 +119,20 @@ export class Evaluator {
|
|
|
113
119
|
throw new Error('Either the application ID or the API key must be provided.');
|
|
114
120
|
}
|
|
115
121
|
|
|
116
|
-
const {baseEndpointUrl
|
|
122
|
+
const {baseEndpointUrl} = configuration;
|
|
123
|
+
const apiKey = typeof configuration.apiKey === 'object'
|
|
124
|
+
? configuration.apiKey.getIdentifier()
|
|
125
|
+
: configuration.apiKey;
|
|
117
126
|
|
|
118
127
|
// eslint-disable-next-line prefer-template -- Better readability
|
|
119
128
|
this.endpoint = (baseEndpointUrl ?? BASE_ENDPOINT_URL).replace(/\/+$/, '')
|
|
120
129
|
+ (apiKey === undefined ? '/client' : '/external')
|
|
121
130
|
+ '/web/evaluate';
|
|
122
|
-
|
|
123
|
-
this.configuration = configuration;
|
|
124
131
|
this.logger = configuration.logger ?? new NullLogger();
|
|
132
|
+
this.configuration = {
|
|
133
|
+
appId: configuration.appId,
|
|
134
|
+
apiKey: apiKey,
|
|
135
|
+
};
|
|
125
136
|
}
|
|
126
137
|
|
|
127
138
|
public evaluate(query: string, options: EvaluationOptions = {}): Promise<JsonValue> {
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import {QueuedEventInfo, TrackingEventProcessor} from './tracker';
|
|
2
|
+
import {Token} from './token';
|
|
3
|
+
import {Logger} from './logging';
|
|
4
|
+
import {TrackingEvent} from './trackingEvents';
|
|
5
|
+
|
|
6
|
+
export class EventSubjectProcessor implements TrackingEventProcessor {
|
|
7
|
+
private currentToken?: Token|null;
|
|
8
|
+
|
|
9
|
+
private logger: Logger;
|
|
10
|
+
|
|
11
|
+
public constructor(logger: Logger) {
|
|
12
|
+
this.logger = logger;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public process(event: QueuedEventInfo): QueuedEventInfo[] {
|
|
16
|
+
const {currentToken} = this;
|
|
17
|
+
|
|
18
|
+
this.currentToken = event.userToken ?? null;
|
|
19
|
+
|
|
20
|
+
if (currentToken === undefined) {
|
|
21
|
+
// This is the first event, no subject to compare.
|
|
22
|
+
// If the user is already identified at this point,
|
|
23
|
+
// assume that the event was previously tracked.
|
|
24
|
+
return [event];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (EventSubjectProcessor.isIdentificationEvent(event.event)) {
|
|
28
|
+
return [event];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const currentSubject = currentToken?.getSubject() ?? null;
|
|
32
|
+
const newSubject = event.userToken?.getSubject() ?? null;
|
|
33
|
+
|
|
34
|
+
if (newSubject === currentSubject) {
|
|
35
|
+
// No change in subject
|
|
36
|
+
return [event];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const events: QueuedEventInfo[] = [];
|
|
40
|
+
|
|
41
|
+
if (currentToken !== null && currentSubject !== null) {
|
|
42
|
+
this.logger.info('External user sign out automatically tracked');
|
|
43
|
+
|
|
44
|
+
events.push({
|
|
45
|
+
timestamp: event.timestamp,
|
|
46
|
+
context: event.context,
|
|
47
|
+
userToken: currentToken,
|
|
48
|
+
event: {
|
|
49
|
+
type: 'userSignedOut',
|
|
50
|
+
userId: currentSubject,
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (newSubject !== null) {
|
|
56
|
+
this.logger.info('External user sign in automatically tracked');
|
|
57
|
+
|
|
58
|
+
events.push({
|
|
59
|
+
timestamp: event.timestamp,
|
|
60
|
+
context: event.context,
|
|
61
|
+
userToken: event.userToken,
|
|
62
|
+
event: {
|
|
63
|
+
type: 'userSignedIn',
|
|
64
|
+
userId: newSubject,
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
events.push(event);
|
|
70
|
+
|
|
71
|
+
return events;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
private static isIdentificationEvent(event: TrackingEvent): boolean {
|
|
75
|
+
switch (event.type) {
|
|
76
|
+
case 'userSignedIn':
|
|
77
|
+
case 'userSignedUp':
|
|
78
|
+
case 'userSignedOut':
|
|
79
|
+
return true;
|
|
80
|
+
|
|
81
|
+
default:
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|