@zoho_apptics/apptics-js-sdk 2.0.0-beta → 2.0.0-beta.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/CHANGELOG.md +191 -21
- package/README.md +519 -333
- package/dist/apptics.esm.min.js +2 -2
- package/dist/apptics.esm.min.js.map +1 -1
- package/dist/apptics.min.js +2 -2
- package/dist/apptics.min.js.map +1 -1
- package/dist/chunks/lifecycle-C6m1W7jo.min.js +3 -0
- package/dist/chunks/lifecycle-C6m1W7jo.min.js.map +1 -0
- package/dist/chunks/send-CgUO82ne.min.js +3 -0
- package/dist/chunks/send-CgUO82ne.min.js.map +1 -0
- package/dist/cjs/core/attempts.js +1 -1
- package/dist/cjs/core/batch.js +2 -2
- package/dist/cjs/core/consent.d.ts +18 -4
- package/dist/cjs/core/consent.js +31 -15
- package/dist/cjs/core/constants.d.ts +57 -27
- package/dist/cjs/core/constants.js +52 -33
- package/dist/cjs/core/db.d.ts +12 -4
- package/dist/cjs/core/db.js +167 -34
- package/dist/cjs/core/debug.js +1 -1
- package/dist/cjs/core/env.d.ts +0 -3
- package/dist/cjs/core/env.js +1 -9
- package/dist/cjs/core/framework-id.d.ts +1 -1
- package/dist/cjs/core/framework-id.js +3 -3
- package/dist/cjs/core/guard.d.ts +9 -0
- package/dist/cjs/core/guard.js +27 -13
- package/dist/cjs/core/hooks.d.ts +7 -4
- package/dist/cjs/core/hooks.js +3 -3
- package/dist/cjs/core/locks.d.ts +9 -0
- package/dist/cjs/core/locks.js +22 -0
- package/dist/cjs/core/logger.d.ts +3 -4
- package/dist/cjs/core/logger.js +4 -40
- package/dist/cjs/core/state.d.ts +9 -6
- package/dist/cjs/core/state.js +3 -5
- package/dist/cjs/core/storage.d.ts +20 -5
- package/dist/cjs/core/storage.js +115 -20
- package/dist/cjs/core/stylesheet.d.ts +8 -0
- package/dist/cjs/core/stylesheet.js +29 -0
- package/dist/cjs/core/transport.d.ts +2 -0
- package/dist/cjs/core/transport.js +30 -18
- package/dist/cjs/core/utils.js +1 -1
- package/dist/cjs/core/validate.js +2 -2
- package/dist/cjs/device/appversion.d.ts +10 -6
- package/dist/cjs/device/appversion.js +38 -3
- package/dist/cjs/device/index.d.ts +28 -2
- package/dist/cjs/device/index.js +312 -44
- package/dist/cjs/engagement/api-rules.d.ts +32 -67
- package/dist/cjs/engagement/api-rules.js +144 -157
- package/dist/cjs/engagement/auto-api.js +2 -2
- package/dist/cjs/engagement/auto-screen.d.ts +2 -0
- package/dist/cjs/engagement/auto-screen.js +67 -3
- package/dist/cjs/engagement/defined-events.js +1 -1
- package/dist/cjs/engagement/send.js +12 -3
- package/dist/cjs/engagement/session.d.ts +29 -3
- package/dist/cjs/engagement/session.js +253 -26
- package/dist/cjs/engagement/track.d.ts +4 -4
- package/dist/cjs/engagement/track.js +58 -30
- package/dist/cjs/errors/send.js +2 -2
- package/dist/cjs/errors/track.d.ts +2 -1
- package/dist/cjs/errors/track.js +49 -7
- package/dist/cjs/feedback/controls.d.ts +12 -0
- package/dist/cjs/feedback/controls.js +104 -25
- package/dist/cjs/feedback/index.d.ts +8 -7
- package/dist/cjs/feedback/index.js +32 -13
- package/dist/cjs/feedback/logs.d.ts +13 -11
- package/dist/cjs/feedback/logs.js +57 -28
- package/dist/cjs/feedback/quartz.d.ts +18 -0
- package/dist/cjs/feedback/quartz.js +105 -0
- package/dist/cjs/feedback/send.d.ts +5 -2
- package/dist/cjs/feedback/send.js +30 -28
- package/dist/cjs/feedback/styles.d.ts +10 -0
- package/dist/cjs/feedback/styles.js +8 -0
- package/dist/cjs/feedback/template.d.ts +1 -1
- package/dist/cjs/feedback/template.js +20 -12
- package/dist/cjs/feedback/ui.d.ts +21 -6
- package/dist/cjs/feedback/ui.js +283 -70
- package/dist/cjs/heatmap/send.d.ts +2 -0
- package/dist/cjs/heatmap/send.js +3 -5
- package/dist/cjs/heatmap/track.d.ts +1 -1
- package/dist/cjs/heatmap/track.js +87 -16
- package/dist/cjs/index.d.ts +16 -63
- package/dist/cjs/index.js +144 -95
- package/dist/cjs/lifecycle.d.ts +21 -3
- package/dist/cjs/lifecycle.js +353 -89
- package/dist/cjs/remoteconfig/country.d.ts +4 -0
- package/dist/cjs/remoteconfig/country.js +73 -0
- package/dist/cjs/remoteconfig/custom.d.ts +7 -7
- package/dist/cjs/remoteconfig/custom.js +31 -51
- package/dist/cjs/remoteconfig/evaluate.d.ts +3 -3
- package/dist/cjs/remoteconfig/evaluate.js +56 -43
- package/dist/cjs/remoteconfig/fetch.d.ts +16 -9
- package/dist/cjs/remoteconfig/fetch.js +120 -39
- package/dist/cjs/remoteconfig/index.d.ts +19 -8
- package/dist/cjs/remoteconfig/index.js +81 -39
- package/dist/cjs/remoteconfig/store.d.ts +15 -7
- package/dist/cjs/remoteconfig/store.js +68 -35
- package/dist/cjs/remoteconfig/tz-countries.d.ts +8 -0
- package/dist/cjs/remoteconfig/tz-countries.js +13 -0
- package/dist/{esm/core → cjs/remotelog}/callsite.d.ts +11 -4
- package/dist/cjs/{core → remotelog}/callsite.js +30 -7
- package/dist/cjs/remotelog/gate.d.ts +2 -11
- package/dist/cjs/remotelog/gate.js +9 -35
- package/dist/cjs/remotelog/index.d.ts +4 -21
- package/dist/cjs/remotelog/logger.d.ts +11 -17
- package/dist/cjs/remotelog/logger.js +31 -59
- package/dist/cjs/remotelog/send.js +11 -11
- package/dist/cjs/remotelogger/index.d.ts +12 -0
- package/dist/cjs/remotelogger/index.js +18 -0
- package/dist/cjs/scheduler.d.ts +3 -1
- package/dist/cjs/scheduler.js +25 -22
- package/dist/cjs/types.d.ts +208 -90
- package/dist/cjs/user/index.js +16 -7
- package/dist/esm/core/attempts.js +1 -1
- package/dist/esm/core/batch.js +2 -2
- package/dist/esm/core/consent.d.ts +18 -4
- package/dist/esm/core/consent.js +32 -17
- package/dist/esm/core/constants.d.ts +57 -27
- package/dist/esm/core/constants.js +51 -33
- package/dist/esm/core/db.d.ts +12 -4
- package/dist/esm/core/db.js +164 -35
- package/dist/esm/core/debug.js +1 -1
- package/dist/esm/core/env.d.ts +0 -3
- package/dist/esm/core/env.js +2 -9
- package/dist/esm/core/framework-id.d.ts +1 -1
- package/dist/esm/core/framework-id.js +3 -3
- package/dist/esm/core/guard.d.ts +9 -0
- package/dist/esm/core/guard.js +27 -14
- package/dist/esm/core/hooks.d.ts +7 -4
- package/dist/esm/core/hooks.js +3 -3
- package/dist/esm/core/locks.d.ts +9 -0
- package/dist/esm/core/locks.js +20 -0
- package/dist/esm/core/logger.d.ts +3 -4
- package/dist/esm/core/logger.js +4 -40
- package/dist/esm/core/state.d.ts +9 -6
- package/dist/esm/core/state.js +3 -5
- package/dist/esm/core/storage.d.ts +20 -5
- package/dist/esm/core/storage.js +113 -21
- package/dist/esm/core/stylesheet.d.ts +8 -0
- package/dist/esm/core/stylesheet.js +27 -0
- package/dist/esm/core/transport.d.ts +2 -0
- package/dist/esm/core/transport.js +30 -19
- package/dist/esm/core/utils.js +1 -1
- package/dist/esm/core/validate.js +2 -2
- package/dist/esm/device/appversion.d.ts +10 -6
- package/dist/esm/device/appversion.js +37 -4
- package/dist/esm/device/index.d.ts +28 -2
- package/dist/esm/device/index.js +313 -49
- package/dist/esm/engagement/api-rules.d.ts +32 -67
- package/dist/esm/engagement/api-rules.js +143 -155
- package/dist/esm/engagement/auto-api.js +3 -3
- package/dist/esm/engagement/auto-screen.d.ts +2 -0
- package/dist/esm/engagement/auto-screen.js +67 -4
- package/dist/esm/engagement/defined-events.js +1 -1
- package/dist/esm/engagement/send.js +12 -3
- package/dist/esm/engagement/session.d.ts +29 -3
- package/dist/esm/engagement/session.js +251 -30
- package/dist/esm/engagement/track.d.ts +4 -4
- package/dist/esm/engagement/track.js +65 -37
- package/dist/esm/errors/send.js +2 -2
- package/dist/esm/errors/track.d.ts +2 -1
- package/dist/esm/errors/track.js +49 -7
- package/dist/esm/feedback/controls.d.ts +12 -0
- package/dist/esm/feedback/controls.js +103 -26
- package/dist/esm/feedback/index.d.ts +8 -7
- package/dist/esm/feedback/index.js +34 -13
- package/dist/esm/feedback/logs.d.ts +13 -11
- package/dist/esm/feedback/logs.js +59 -30
- package/dist/esm/feedback/quartz.d.ts +18 -0
- package/dist/esm/feedback/quartz.js +99 -0
- package/dist/esm/feedback/send.d.ts +5 -2
- package/dist/esm/feedback/send.js +31 -31
- package/dist/esm/feedback/styles.d.ts +10 -0
- package/dist/esm/feedback/styles.js +4 -0
- package/dist/esm/feedback/template.d.ts +1 -1
- package/dist/esm/feedback/template.js +20 -12
- package/dist/esm/feedback/ui.d.ts +21 -6
- package/dist/esm/feedback/ui.js +283 -71
- package/dist/esm/heatmap/send.d.ts +2 -0
- package/dist/esm/heatmap/send.js +3 -5
- package/dist/esm/heatmap/track.d.ts +1 -1
- package/dist/esm/heatmap/track.js +87 -16
- package/dist/esm/index.d.ts +16 -63
- package/dist/esm/index.js +148 -83
- package/dist/esm/lifecycle.d.ts +21 -3
- package/dist/esm/lifecycle.js +359 -98
- package/dist/esm/remoteconfig/country.d.ts +4 -0
- package/dist/esm/remoteconfig/country.js +70 -0
- package/dist/esm/remoteconfig/custom.d.ts +7 -7
- package/dist/esm/remoteconfig/custom.js +32 -52
- package/dist/esm/remoteconfig/evaluate.d.ts +3 -3
- package/dist/esm/remoteconfig/evaluate.js +57 -44
- package/dist/esm/remoteconfig/fetch.d.ts +16 -9
- package/dist/esm/remoteconfig/fetch.js +120 -39
- package/dist/esm/remoteconfig/index.d.ts +19 -8
- package/dist/esm/remoteconfig/index.js +82 -40
- package/dist/esm/remoteconfig/store.d.ts +15 -7
- package/dist/esm/remoteconfig/store.js +68 -36
- package/dist/esm/remoteconfig/tz-countries.d.ts +8 -0
- package/dist/esm/remoteconfig/tz-countries.js +11 -0
- package/dist/{cjs/core → esm/remotelog}/callsite.d.ts +11 -4
- package/dist/esm/{core → remotelog}/callsite.js +30 -8
- package/dist/esm/remotelog/gate.d.ts +2 -11
- package/dist/esm/remotelog/gate.js +10 -32
- package/dist/esm/remotelog/index.d.ts +4 -21
- package/dist/esm/remotelog/logger.d.ts +11 -17
- package/dist/esm/remotelog/logger.js +33 -61
- package/dist/esm/remotelog/send.js +13 -13
- package/dist/esm/remotelogger/index.d.ts +12 -0
- package/dist/esm/remotelogger/index.js +13 -0
- package/dist/esm/scheduler.d.ts +3 -1
- package/dist/esm/scheduler.js +26 -24
- package/dist/esm/types.d.ts +208 -90
- package/dist/esm/user/index.js +18 -8
- package/dist/feedback.esm.min.js +2 -2
- package/dist/feedback.esm.min.js.map +1 -1
- package/dist/remoteconfig.esm.min.js +3 -0
- package/dist/remoteconfig.esm.min.js.map +1 -0
- package/dist/remotelogger.esm.min.js +3 -0
- package/dist/remotelogger.esm.min.js.map +1 -0
- package/package.json +16 -17
- package/dist/chunks/batch-BU_mTpm1.min.js +0 -3
- package/dist/chunks/batch-BU_mTpm1.min.js.map +0 -1
- package/dist/chunks/logs-Bea5zUW_.min.js +0 -3
- package/dist/chunks/logs-Bea5zUW_.min.js.map +0 -1
- package/dist/cjs/auto-init.d.ts +0 -8
- package/dist/cjs/auto-init.js +0 -32
- package/dist/cjs/heatmap/index.d.ts +0 -16
- package/dist/cjs/heatmap/index.js +0 -22
- package/dist/cjs/remotelog/index.js +0 -55
- package/dist/esm/auto-init.d.ts +0 -8
- package/dist/esm/auto-init.js +0 -29
- package/dist/esm/heatmap/index.d.ts +0 -16
- package/dist/esm/heatmap/index.js +0 -17
- package/dist/esm/remotelog/index.js +0 -51
- package/dist/heatmap.esm.min.js +0 -3
- package/dist/heatmap.esm.min.js.map +0 -1
- package/dist/style.css +0 -1
package/dist/cjs/core/state.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type ApConfig } from './constants.js';
|
|
2
|
-
import type { DeviceInfo, Dict, TrackingStatus, UserInfo } from '../types.js';
|
|
1
|
+
import { type ApConfig, type EngagementType } from './constants.js';
|
|
2
|
+
import type { DeviceInfo, Dict, QuartzSettings, TrackingStatus, UserInfo } from '../types.js';
|
|
3
3
|
/** Runtime state shared by every module (the former `_ZAP` object). */
|
|
4
4
|
export interface State {
|
|
5
5
|
_initialised: boolean;
|
|
@@ -19,7 +19,6 @@ export interface State {
|
|
|
19
19
|
_token: string;
|
|
20
20
|
_frameworkID: number;
|
|
21
21
|
_platform: string;
|
|
22
|
-
_isanonrequired: boolean;
|
|
23
22
|
_devicestatus: TrackingStatus;
|
|
24
23
|
_uuid: string;
|
|
25
24
|
_apid: string;
|
|
@@ -30,9 +29,12 @@ export interface State {
|
|
|
30
29
|
_current_session: Dict;
|
|
31
30
|
_properties: Dict;
|
|
32
31
|
_ignoreDnt: boolean;
|
|
33
|
-
_isGlobalErrorTracking: boolean;
|
|
34
32
|
_shouldTrack: boolean;
|
|
35
|
-
|
|
33
|
+
/**
|
|
34
|
+
* getsdkconfig's engagement modules, one per kind of item, keyed by the item's type: event (5),
|
|
35
|
+
* api (6), screen (10) and session (11).
|
|
36
|
+
*/
|
|
37
|
+
_engagementTracking: Record<EngagementType, boolean>;
|
|
36
38
|
_errorTracking: boolean;
|
|
37
39
|
/** getsdkconfig module 18. Heatmap has its own flag in v2; before that it rode engagement. */
|
|
38
40
|
_heatmapTracking: boolean;
|
|
@@ -44,7 +46,8 @@ export interface State {
|
|
|
44
46
|
_remoteConfigReported: boolean;
|
|
45
47
|
/** getsdkconfig module 12. */
|
|
46
48
|
_feedbackEnabled: boolean;
|
|
47
|
-
|
|
49
|
+
/** getsdkconfig's `quartz` block: screen recording in the feedback form. Off until it says otherwise. */
|
|
50
|
+
_quartz: QuartzSettings;
|
|
48
51
|
/** Epoch ms getsdkconfig asked us to wait until before asking again. 0 means no answer yet. */
|
|
49
52
|
_nextConfigCheck: number;
|
|
50
53
|
/**
|
package/dist/cjs/core/state.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var constants = require('./constants.js');
|
|
@@ -23,7 +23,6 @@ function initialState() {
|
|
|
23
23
|
// issued by Apptics at pack time; see scripts/register-version.mjs
|
|
24
24
|
_frameworkID: frameworkId.FRAMEWORK_ID,
|
|
25
25
|
_platform: constants.AP_CONSTANTS.BROWSER,
|
|
26
|
-
_isanonrequired: true,
|
|
27
26
|
_devicestatus: constants.AP_TRACKING_STATUS.USAGE_TRACKING_WITHOUT_PII,
|
|
28
27
|
_uuid: '', // no i18n
|
|
29
28
|
_apid: '', // no i18n
|
|
@@ -34,9 +33,8 @@ function initialState() {
|
|
|
34
33
|
_current_session: {},
|
|
35
34
|
_properties: {},
|
|
36
35
|
_ignoreDnt: false,
|
|
37
|
-
_isGlobalErrorTracking: true,
|
|
38
36
|
_shouldTrack: true,
|
|
39
|
-
_engagementTracking: true,
|
|
37
|
+
_engagementTracking: { event: true, screen: true, session: true, api: true },
|
|
40
38
|
_heatmapTracking: true,
|
|
41
39
|
_remoteLoggerEnabled: true,
|
|
42
40
|
_remoteConfigEnabled: true,
|
|
@@ -45,7 +43,7 @@ function initialState() {
|
|
|
45
43
|
_nextConfigCheck: 0,
|
|
46
44
|
_debugUntil: 0,
|
|
47
45
|
_errorTracking: true,
|
|
48
|
-
|
|
46
|
+
_quartz: { enabled: false, workspace: '', department: '', domain: '', cdnUrl: '' }, // no i18n
|
|
49
47
|
_trackinfo: {},
|
|
50
48
|
};
|
|
51
49
|
}
|
|
@@ -20,23 +20,38 @@ export declare const error_transactions: Queue;
|
|
|
20
20
|
* These are not sent on their own: feedback/logs.ts renders them into the files that
|
|
21
21
|
* feedback/add carries, and removes the ones a submission took with it.
|
|
22
22
|
*/
|
|
23
|
-
export declare const
|
|
23
|
+
export declare const feedbacklog_transactions: Queue;
|
|
24
24
|
/** Clicks and scrolls waiting for heatmap/add. */
|
|
25
25
|
export declare const heatmap_transactions: Queue;
|
|
26
26
|
/**
|
|
27
|
-
* Remote log lines waiting for
|
|
27
|
+
* Remote log lines waiting for log/add. Stored rather than sent straight out because the
|
|
28
28
|
* endpoint takes one line per call and counts retries (`attempt`), so a line has to outlive a
|
|
29
29
|
* failed send — and a reload.
|
|
30
30
|
*/
|
|
31
|
-
export declare const
|
|
32
|
-
/**
|
|
31
|
+
export declare const remotelog_transactions: Queue;
|
|
32
|
+
/**
|
|
33
|
+
* Sets one key of the stored device_info, and of this tab's copy: the uuid the device is
|
|
34
|
+
* registered under, whether it has had a session. Its other keys stay as they are.
|
|
35
|
+
*/
|
|
36
|
+
export declare function setDeviceInfoKey(key: string, value: unknown): void;
|
|
37
|
+
/** device_info (uuid included), app_version_info, trackinfo (tracking_status included), users, user_info, and the rest. */
|
|
33
38
|
export declare const user_defaults: {
|
|
34
39
|
all(): Dict;
|
|
35
40
|
item(key: string): any;
|
|
36
41
|
add(key: string, value: unknown): void;
|
|
42
|
+
/** As add(), and resolves once the value is in storage, where other tabs can read it. */
|
|
43
|
+
save(key: string, value: unknown): Promise<void>;
|
|
37
44
|
clear(): void;
|
|
38
45
|
};
|
|
39
|
-
/**
|
|
46
|
+
/**
|
|
47
|
+
* Re-reads `keys` from storage. Settings are loaded into memory once, when a tab starts, so a value
|
|
48
|
+
* another tab of this site wrote since then — the device ids it registered — is only in storage.
|
|
49
|
+
* A key storage doesn't hold keeps this tab's value.
|
|
50
|
+
*/
|
|
51
|
+
export declare function reloadSettings(keys: string[]): Promise<void>;
|
|
52
|
+
/** The visitor's tracking status, stored in trackinfo as tracking_status. */
|
|
53
|
+
export declare function storedTrackingStatus(): TrackingStatus | undefined;
|
|
54
|
+
/** Opt-in status, stored in the trackinfo setting as tracking_status. */
|
|
40
55
|
export declare const tracking_preference: {
|
|
41
56
|
_tracking_status: string;
|
|
42
57
|
all(): Dict;
|
package/dist/cjs/core/storage.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var constants = require('./constants.js');
|
|
@@ -30,8 +30,6 @@ function migrateLegacy(b) {
|
|
|
30
30
|
errors: localStorage.getItem(db.LEGACY_KEYS.errors),
|
|
31
31
|
logs: localStorage.getItem(db.LEGACY_KEYS.logs),
|
|
32
32
|
consolelogs: localStorage.getItem(db.LEGACY_KEYS.consolelogs),
|
|
33
|
-
// read for completeness of the shape only: 1.x never wrote this key
|
|
34
|
-
heatmaps: null,
|
|
35
33
|
};
|
|
36
34
|
}
|
|
37
35
|
catch (err) {
|
|
@@ -49,15 +47,17 @@ function migrateLegacy(b) {
|
|
|
49
47
|
return null;
|
|
50
48
|
}
|
|
51
49
|
};
|
|
50
|
+
// 1.x's keys are logs and consolelogs; they are feedbacklogs and remotelogs now, and a
|
|
51
|
+
// feedback entry's type is feedbacklog or feedbackdiagnostics instead of log or diagnostics
|
|
52
52
|
var queues = {
|
|
53
53
|
engagements: db.asList(parse(raw.engagements)),
|
|
54
54
|
errors: db.asList(parse(raw.errors)),
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
feedbacklogs: db.asList(parse(raw.logs)).map(db.renameFeedbackType),
|
|
56
|
+
remotelogs: db.asList(parse(raw.consolelogs)),
|
|
57
57
|
// nothing to migrate: 1.x had no heatmaps
|
|
58
58
|
heatmaps: [],
|
|
59
59
|
};
|
|
60
|
-
queues.engagements.concat(queues.errors, queues.
|
|
60
|
+
queues.engagements.concat(queues.errors, queues.feedbacklogs, queues.remotelogs).forEach(function (item) {
|
|
61
61
|
if (!item.id)
|
|
62
62
|
item.id = utils.getNewUUID();
|
|
63
63
|
});
|
|
@@ -91,6 +91,7 @@ function storageReady() {
|
|
|
91
91
|
}).then(function (loaded) {
|
|
92
92
|
// writes made before loading finished win over stored values
|
|
93
93
|
settings = Object.assign({}, loaded, settings);
|
|
94
|
+
moveRetiredSettings();
|
|
94
95
|
return b;
|
|
95
96
|
});
|
|
96
97
|
}).catch(function (err) {
|
|
@@ -161,21 +162,75 @@ const error_transactions = createQueue('errors'); // no i18n
|
|
|
161
162
|
* These are not sent on their own: feedback/logs.ts renders them into the files that
|
|
162
163
|
* feedback/add carries, and removes the ones a submission took with it.
|
|
163
164
|
*/
|
|
164
|
-
const
|
|
165
|
+
const feedbacklog_transactions = createQueue('feedbacklogs'); // no i18n
|
|
165
166
|
/** Clicks and scrolls waiting for heatmap/add. */
|
|
166
167
|
const heatmap_transactions = createQueue('heatmaps'); // no i18n
|
|
167
168
|
/**
|
|
168
|
-
* Remote log lines waiting for
|
|
169
|
+
* Remote log lines waiting for log/add. Stored rather than sent straight out because the
|
|
169
170
|
* endpoint takes one line per call and counts retries (`attempt`), so a line has to outlive a
|
|
170
171
|
* failed send — and a reload.
|
|
171
172
|
*/
|
|
172
|
-
const
|
|
173
|
+
const remotelog_transactions = createQueue('remotelogs'); // no i18n
|
|
173
174
|
/* ---------------- settings (sync reads, background writes) ---------------- */
|
|
175
|
+
/** Writes `key`, or removes it from storage altogether when `value` is undefined. */
|
|
176
|
+
function writeSetting(b, key) {
|
|
177
|
+
return settings[key] === undefined ? b.deleteSetting(key) : b.putSetting(key, settings[key]);
|
|
178
|
+
}
|
|
174
179
|
function setSetting(key, value) {
|
|
175
|
-
|
|
176
|
-
|
|
180
|
+
if (value === undefined) {
|
|
181
|
+
delete settings[key];
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
settings[key] = utils.cloneObject(value);
|
|
185
|
+
}
|
|
186
|
+
withBackend('save ' + key, undefined, function (b) { return writeSetting(b, key); }); // no i18n
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Settings 2.0.0-beta kept as keys of their own, now kept inside device_info and trackinfo.
|
|
190
|
+
* Moved once, on the first load after an upgrade, before anything reads them: the uuid is the one
|
|
191
|
+
* the device is registered under, and the tracking status is the visitor's own choice, so losing
|
|
192
|
+
* either would register a new device or forget a consent. token was never read, and goes.
|
|
193
|
+
* appkey and appversion are read and removed by init(), which compares them with this visit's app.
|
|
194
|
+
*/
|
|
195
|
+
function moveRetiredSettings() {
|
|
196
|
+
var device = settings.device_info && typeof settings.device_info === 'object' ? settings.device_info : null; // no i18n
|
|
197
|
+
if (settings.uuid !== undefined || settings.hadsession !== undefined) {
|
|
198
|
+
device = Object.assign({}, device || {});
|
|
199
|
+
if (utils.isEmpty(device.uuid) && !utils.isEmpty(settings.uuid)) {
|
|
200
|
+
device.uuid = settings.uuid;
|
|
201
|
+
}
|
|
202
|
+
if (settings.hadsession === true) {
|
|
203
|
+
device.hadsession = true;
|
|
204
|
+
}
|
|
205
|
+
setSetting('device_info', device); // no i18n
|
|
206
|
+
setSetting('uuid', undefined); // no i18n
|
|
207
|
+
setSetting('hadsession', undefined); // no i18n
|
|
208
|
+
}
|
|
209
|
+
if (settings.tracking_status !== undefined) {
|
|
210
|
+
var track = Object.assign({}, settings.trackinfo && typeof settings.trackinfo === 'object' ? settings.trackinfo : {}); // no i18n
|
|
211
|
+
if (track.tracking_status === undefined) {
|
|
212
|
+
track.tracking_status = settings.tracking_status;
|
|
213
|
+
}
|
|
214
|
+
setSetting('trackinfo', track); // no i18n
|
|
215
|
+
setSetting('tracking_status', undefined); // no i18n
|
|
216
|
+
}
|
|
217
|
+
if (settings.token !== undefined) {
|
|
218
|
+
setSetting('token', undefined); // no i18n
|
|
219
|
+
}
|
|
177
220
|
}
|
|
178
|
-
/**
|
|
221
|
+
/**
|
|
222
|
+
* Sets one key of the stored device_info, and of this tab's copy: the uuid the device is
|
|
223
|
+
* registered under, whether it has had a session. Its other keys stay as they are.
|
|
224
|
+
*/
|
|
225
|
+
function setDeviceInfoKey(key, value) {
|
|
226
|
+
var device = Object.assign({}, settings.device_info && typeof settings.device_info === 'object' ? settings.device_info : {}); // no i18n
|
|
227
|
+
device[key] = value;
|
|
228
|
+
if (state._ZAP._device_info && typeof state._ZAP._device_info === 'object') { // no i18n
|
|
229
|
+
state._ZAP._device_info[key] = value;
|
|
230
|
+
}
|
|
231
|
+
setSetting('device_info', device); // no i18n
|
|
232
|
+
}
|
|
233
|
+
/** device_info (uuid included), app_version_info, trackinfo (tracking_status included), users, user_info, and the rest. */
|
|
179
234
|
const user_defaults = {
|
|
180
235
|
all() {
|
|
181
236
|
return utils.cloneObject(settings);
|
|
@@ -187,26 +242,63 @@ const user_defaults = {
|
|
|
187
242
|
add(key, value) {
|
|
188
243
|
setSetting(key, value);
|
|
189
244
|
},
|
|
245
|
+
/** As add(), and resolves once the value is in storage, where other tabs can read it. */
|
|
246
|
+
save(key, value) {
|
|
247
|
+
if (value === undefined) {
|
|
248
|
+
delete settings[key];
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
settings[key] = utils.cloneObject(value);
|
|
252
|
+
}
|
|
253
|
+
return withBackend('save ' + key, undefined, function (b) { return writeSetting(b, key); }); // no i18n
|
|
254
|
+
},
|
|
190
255
|
clear() {
|
|
191
256
|
settings = {};
|
|
192
257
|
withBackend('clear settings', undefined, function (b) { return b.clearSettings(); }); // no i18n
|
|
193
258
|
},
|
|
194
259
|
};
|
|
195
|
-
/**
|
|
260
|
+
/**
|
|
261
|
+
* Re-reads `keys` from storage. Settings are loaded into memory once, when a tab starts, so a value
|
|
262
|
+
* another tab of this site wrote since then — the device ids it registered — is only in storage.
|
|
263
|
+
* A key storage doesn't hold keeps this tab's value.
|
|
264
|
+
*/
|
|
265
|
+
function reloadSettings(keys) {
|
|
266
|
+
return withBackend('reload settings', undefined, function (b) {
|
|
267
|
+
return b.loadSettings().then(function (loaded) {
|
|
268
|
+
keys.forEach(function (key) {
|
|
269
|
+
if (loaded[key] !== undefined) {
|
|
270
|
+
settings[key] = loaded[key];
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
/** The visitor's tracking status, stored in trackinfo as tracking_status. */
|
|
277
|
+
function storedTrackingStatus() {
|
|
278
|
+
var track = settings.trackinfo;
|
|
279
|
+
var status = track && typeof track === 'object' ? track.tracking_status : undefined; // no i18n
|
|
280
|
+
// a status only: getsdkconfig's own answer uses the same key for its per-module flags, and
|
|
281
|
+
// one stored by mistake must not read as a consent and stop all tracking
|
|
282
|
+
return status === constants.AP_TRACKING_STATUS.USAGE_TRACKING_WITH_PII || status === constants.AP_TRACKING_STATUS.USAGE_TRACKING_WITHOUT_PII
|
|
283
|
+
|| status === constants.AP_TRACKING_STATUS.NO_TRACKING ? status : undefined;
|
|
284
|
+
}
|
|
285
|
+
/** Opt-in status, stored in the trackinfo setting as tracking_status. */
|
|
196
286
|
const tracking_preference = {
|
|
197
287
|
_tracking_status: 'tracking_status', // no i18n
|
|
198
288
|
all() {
|
|
199
289
|
return user_defaults.all();
|
|
200
290
|
},
|
|
201
291
|
opt_in_status() {
|
|
202
|
-
return (
|
|
292
|
+
return (storedTrackingStatus() || constants.AP_TRACKING_STATUS.USAGE_TRACKING_WITHOUT_PII);
|
|
203
293
|
},
|
|
204
294
|
update_status(tracking_status) {
|
|
205
295
|
state._ZAP._devicestatus = tracking_status;
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
296
|
+
var track = Object.assign({}, settings.trackinfo && typeof settings.trackinfo === 'object' ? settings.trackinfo : {}); // no i18n
|
|
297
|
+
track.tracking_status = tracking_status;
|
|
298
|
+
if (state._ZAP._trackinfo && typeof state._ZAP._trackinfo === 'object') { // no i18n
|
|
299
|
+
state._ZAP._trackinfo.tracking_status = tracking_status;
|
|
300
|
+
}
|
|
301
|
+
setSetting('trackinfo', track); // no i18n
|
|
210
302
|
},
|
|
211
303
|
};
|
|
212
304
|
function getKeyFromDeviceInfo(key) {
|
|
@@ -218,12 +310,15 @@ function getKeyFromDeviceInfo(key) {
|
|
|
218
310
|
return null;
|
|
219
311
|
}
|
|
220
312
|
|
|
221
|
-
exports.consolelog_transactions = consolelog_transactions;
|
|
222
313
|
exports.engagement_transactions = engagement_transactions;
|
|
223
314
|
exports.error_transactions = error_transactions;
|
|
315
|
+
exports.feedbacklog_transactions = feedbacklog_transactions;
|
|
224
316
|
exports.getKeyFromDeviceInfo = getKeyFromDeviceInfo;
|
|
225
317
|
exports.heatmap_transactions = heatmap_transactions;
|
|
226
|
-
exports.
|
|
318
|
+
exports.reloadSettings = reloadSettings;
|
|
319
|
+
exports.remotelog_transactions = remotelog_transactions;
|
|
320
|
+
exports.setDeviceInfoKey = setDeviceInfoKey;
|
|
227
321
|
exports.storageReady = storageReady;
|
|
322
|
+
exports.storedTrackingStatus = storedTrackingStatus;
|
|
228
323
|
exports.tracking_preference = tracking_preference;
|
|
229
324
|
exports.user_defaults = user_defaults;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adds the feedback form's styles to the page, once, as a <style> element, so no app imports or
|
|
3
|
+
* links a stylesheet: the css is carried in the JavaScript, for npm and the CDN builds alike.
|
|
4
|
+
*
|
|
5
|
+
* Nothing happens when `css` is empty (running from source, as the tests do) or when the page
|
|
6
|
+
* already has the styles (the element is marked data-apptics="style"). Never throws.
|
|
7
|
+
*/
|
|
8
|
+
export declare function injectStylesheet(css: string): void;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Adds the feedback form's styles to the page, once, as a <style> element, so no app imports or
|
|
6
|
+
* links a stylesheet: the css is carried in the JavaScript, for npm and the CDN builds alike.
|
|
7
|
+
*
|
|
8
|
+
* Nothing happens when `css` is empty (running from source, as the tests do) or when the page
|
|
9
|
+
* already has the styles (the element is marked data-apptics="style"). Never throws.
|
|
10
|
+
*/
|
|
11
|
+
function injectStylesheet(css) {
|
|
12
|
+
try {
|
|
13
|
+
if (!css || typeof document === 'undefined') { // no i18n
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (document.querySelector('[data-apptics="style"]')) { // no i18n
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
var style = document.createElement('style'); // no i18n
|
|
20
|
+
style.setAttribute('data-apptics', 'style'); // no i18n
|
|
21
|
+
style.textContent = css;
|
|
22
|
+
(document.head || document.documentElement).appendChild(style);
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
// the form still works unstyled; the app must not break over a stylesheet
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
exports.injectStylesheet = injectStylesheet;
|
|
@@ -81,3 +81,5 @@ export declare function getMetaObj(): Dict;
|
|
|
81
81
|
* and feedback (P11).
|
|
82
82
|
*/
|
|
83
83
|
export declare function rejectIfNoDeviceIds(label: string): Promise<never> | null;
|
|
84
|
+
/** Whether device/add has given this browser its deviceid. */
|
|
85
|
+
export declare function hasDeviceId(): boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var constants = require('./constants.js');
|
|
@@ -141,19 +141,17 @@ function getParameters(path) {
|
|
|
141
141
|
// v2 device/add declares neither identifier, platform nor appversion: the build is already
|
|
142
142
|
// known from app/addversion, and sending an undeclared param is refused as EXTRA_PARAM_FOUND.
|
|
143
143
|
// What it does declare as mandatory is appversionid, which v1 treated as optional.
|
|
144
|
+
// isanonrequired is always false: the web SDK has no anonymous mode, only the tracking
|
|
145
|
+
// statuses (with PII, without PII, none), which devicestatus carries.
|
|
144
146
|
if (path == 'regdevice') { // no i18n
|
|
145
|
-
returnVal = '?isanonrequired=
|
|
147
|
+
returnVal = '?isanonrequired=false&devicestatus=' + state._ZAP._devicestatus; // no i18n
|
|
146
148
|
if (!utils.isEmpty(state._ZAP._device_info.deviceid)) {
|
|
147
149
|
returnVal += '&deviceid=' + encodeURIComponent(String(state._ZAP._device_info.deviceid)); // no i18n
|
|
148
150
|
}
|
|
149
151
|
return returnVal + mandatoryParams(returnVal);
|
|
150
152
|
}
|
|
151
|
-
// getsdkconfig
|
|
152
|
-
|
|
153
|
-
// with NOT_AUTHENTICATED. getupdates declares the same param with plain paramdecrypt, so it
|
|
154
|
-
// does carry one. It still needs appversionid and frameworkid, added at the end.
|
|
155
|
-
var identifiesDevice = path != 'sdkconfig'; // no i18n
|
|
156
|
-
if (identifiesDevice) {
|
|
153
|
+
// getsdkconfig carries no deviceid: the user's ids below are what it answers for
|
|
154
|
+
if (path != 'sdkconfig') { // no i18n
|
|
157
155
|
if (utils.isEmpty(state._ZAP._device_info.deviceid)) {
|
|
158
156
|
hooks.hooks.refreshDeviceInfo();
|
|
159
157
|
// the device is missing, but appversionid and frameworkid are mandatory regardless:
|
|
@@ -174,15 +172,17 @@ function getParameters(path) {
|
|
|
174
172
|
}
|
|
175
173
|
return returnVal + mandatoryParams(returnVal);
|
|
176
174
|
}
|
|
177
|
-
// add userid and groupid if opt_in_status is USAGE_TRACKING_WITH_PII
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
175
|
+
// add userid and groupid if opt_in_status is USAGE_TRACKING_WITH_PII. getupdates doesn't declare
|
|
176
|
+
// them, and refuses userid as EXTRA_PARAM_FOUND; it has no use for them either, since remote
|
|
177
|
+
// config conditions on the user are evaluated here, against the rule set it answers with
|
|
178
|
+
var carriesUser = path != 'reguser' && path != 'getupdates'; // no i18n
|
|
179
|
+
if (carriesUser && consent.opt_in_status() == constants.AP_TRACKING_STATUS.USAGE_TRACKING_WITH_PII) {
|
|
180
|
+
if (state._ZAP._user_info.hasOwnProperty('userid') && !utils.isEmpty(state._ZAP._user_info.userid)) { // no i18n
|
|
181
|
+
// getsdkconfig has no deviceid before it, so its userid starts the query
|
|
182
|
+
returnVal += (returnVal === '' ? '?' : '&') + 'userid=' + encodeURIComponent(String(state._ZAP._user_info.userid)); // no i18n
|
|
183
|
+
}
|
|
184
|
+
if (state._ZAP._user_info.hasOwnProperty('groupid') && !utils.isEmpty(state._ZAP._user_info.groupid)) { // no i18n
|
|
185
|
+
returnVal += (returnVal === '' ? '?' : '&') + 'customergroupid=' + encodeURIComponent(String(state._ZAP._user_info.groupid)); // no i18n
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
188
|
returnVal += deviceNameParam(path, returnVal);
|
|
@@ -419,10 +419,21 @@ function getMetaObj() {
|
|
|
419
419
|
function rejectIfNoDeviceIds(label) {
|
|
420
420
|
if (utils.isEmpty(getHeaderParams('apid')) && utils.isEmpty(getHeaderParams('mapid'))) { // no i18n
|
|
421
421
|
hooks.hooks.refreshDeviceInfo();
|
|
422
|
-
return Promise.reject(label + ': You must call
|
|
422
|
+
return Promise.reject(label + ': You must call Apptics.init() first'); // no i18n
|
|
423
|
+
}
|
|
424
|
+
// app/addversion has answered, device/add not yet (offline, or it failed): what is stored waits
|
|
425
|
+
// for the device it belongs to rather than going out without a deviceid. The refresh registers
|
|
426
|
+
// the device, joining a registration already in flight
|
|
427
|
+
if (!hasDeviceId()) {
|
|
428
|
+
hooks.hooks.refreshDeviceInfo();
|
|
429
|
+
return Promise.reject(label + ': the device is not registered yet, kept for the next send'); // no i18n
|
|
423
430
|
}
|
|
424
431
|
return null;
|
|
425
432
|
}
|
|
433
|
+
/** Whether device/add has given this browser its deviceid. */
|
|
434
|
+
function hasDeviceId() {
|
|
435
|
+
return !utils.isEmpty(state._ZAP._device_info && state._ZAP._device_info.deviceid) || !utils.isEmpty(storage.getKeyFromDeviceInfo('deviceid')); // no i18n
|
|
436
|
+
}
|
|
426
437
|
|
|
427
438
|
exports.KEEPALIVE_BUDGET = KEEPALIVE_BUDGET;
|
|
428
439
|
exports.REQUEST_TIMEOUT_MS = REQUEST_TIMEOUT_MS;
|
|
@@ -431,6 +442,7 @@ exports.getHeaderParams = getHeaderParams;
|
|
|
431
442
|
exports.getMetaObj = getMetaObj;
|
|
432
443
|
exports.getParameters = getParameters;
|
|
433
444
|
exports.getUrlWithParams = getUrlWithParams;
|
|
445
|
+
exports.hasDeviceId = hasDeviceId;
|
|
434
446
|
exports.isPermanentRefusal = isPermanentRefusal;
|
|
435
447
|
exports.makeRequest = makeRequest;
|
|
436
448
|
exports.postKeepalive = postKeepalive;
|
package/dist/cjs/core/utils.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var logger = require('./logger.js');
|
|
@@ -220,7 +220,7 @@ function validateScreenName(str) {
|
|
|
220
220
|
}
|
|
221
221
|
// Define the regular expression pattern
|
|
222
222
|
//^[a-zA-Z][\\w\\s]{1,100}$
|
|
223
|
-
const pattern = /^[\w\s.\-_
|
|
223
|
+
const pattern = /^[\w\s.\-_&/:*]{0,99}$/;
|
|
224
224
|
// Test if the string matches the pattern
|
|
225
225
|
return pattern.test(str);
|
|
226
226
|
}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
/** Whether we already hold usable ids for the app and version running now. */
|
|
2
|
-
export declare function hasAppVersion(): boolean;
|
|
3
1
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* rather than carrying on to calls that would be refused for missing them.
|
|
2
|
+
* A fingerprint of the auth key, which is what is stored to tell one key from another: enough to
|
|
3
|
+
* notice that init() was given a different one, without keeping a second copy of the key itself.
|
|
4
|
+
* FNV-1a, 32 bits, as hex; '' for no key.
|
|
8
5
|
*/
|
|
6
|
+
export declare function keyFingerprint(key: unknown): string;
|
|
7
|
+
/**
|
|
8
|
+
* Whether we already hold usable ids for the app, auth key and version running now. Ids stored by
|
|
9
|
+
* a build that kept no key fingerprint register again once, and the answer then records it.
|
|
10
|
+
*/
|
|
11
|
+
export declare function hasAppVersion(): boolean;
|
|
12
|
+
export declare function appVersionFailedForNetwork(): boolean;
|
|
9
13
|
export declare function registerAppVersion(): Promise<boolean>;
|
|
10
14
|
/**
|
|
11
15
|
* Puts the stored ids back on `_ZAP._device_info`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
1
|
+
/*! @zoho_apptics/apptics-js-sdk v2.0.0-beta.2 | (c) Zoho Corporation Private Limited | see LICENSE */
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var state = require('../core/state.js');
|
|
@@ -39,13 +39,34 @@ const REQUIRED_KEYS = ['aaid', 'portalid', 'projectid', 'apid', 'mapid', 'appver
|
|
|
39
39
|
function missingKeys(data) {
|
|
40
40
|
return REQUIRED_KEYS.filter(function (key) { return utils.isEmpty(data[key]); });
|
|
41
41
|
}
|
|
42
|
-
/**
|
|
42
|
+
/**
|
|
43
|
+
* A fingerprint of the auth key, which is what is stored to tell one key from another: enough to
|
|
44
|
+
* notice that init() was given a different one, without keeping a second copy of the key itself.
|
|
45
|
+
* FNV-1a, 32 bits, as hex; '' for no key.
|
|
46
|
+
*/
|
|
47
|
+
function keyFingerprint(key) {
|
|
48
|
+
var text = utils.isEmpty(key) ? '' : String(key); // no i18n
|
|
49
|
+
if (text === '') { // no i18n
|
|
50
|
+
return ''; // no i18n
|
|
51
|
+
}
|
|
52
|
+
var hash = 0x811c9dc5;
|
|
53
|
+
for (var i = 0; i < text.length; i++) {
|
|
54
|
+
hash ^= text.charCodeAt(i);
|
|
55
|
+
hash = Math.imul(hash, 0x01000193) >>> 0;
|
|
56
|
+
}
|
|
57
|
+
return ('0000000' + hash.toString(16)).slice(-8); // no i18n
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Whether we already hold usable ids for the app, auth key and version running now. Ids stored by
|
|
61
|
+
* a build that kept no key fingerprint register again once, and the answer then records it.
|
|
62
|
+
*/
|
|
43
63
|
function hasAppVersion() {
|
|
44
64
|
var saved = stored();
|
|
45
65
|
return missingKeys(saved).length === 0
|
|
46
66
|
&& saved.appversion === state._ZAP._defaultoptions.appversion
|
|
47
67
|
&& saved.identifier === state._ZAP._defaultoptions.identifier
|
|
48
|
-
&& saved.serviceUrl === state._ZAP._defaultoptions.serviceUrl
|
|
68
|
+
&& saved.serviceUrl === state._ZAP._defaultoptions.serviceUrl
|
|
69
|
+
&& saved.zakhash === keyFingerprint(state._ZAP._defaultoptions.zak);
|
|
49
70
|
}
|
|
50
71
|
/** Puts the ids where the rest of the SDK reads them from. */
|
|
51
72
|
function apply(data) {
|
|
@@ -80,7 +101,16 @@ function apply(data) {
|
|
|
80
101
|
* Resolves true when the ids are in place, false when they are not — the caller stops there
|
|
81
102
|
* rather than carrying on to calls that would be refused for missing them.
|
|
82
103
|
*/
|
|
104
|
+
/**
|
|
105
|
+
* Whether the last registration failed for want of a network (offline, a dropped connection, a
|
|
106
|
+
* timeout) rather than because the server answered no. Only the first is worth trying again.
|
|
107
|
+
*/
|
|
108
|
+
var failedForNetwork = false;
|
|
109
|
+
function appVersionFailedForNetwork() {
|
|
110
|
+
return failedForNetwork;
|
|
111
|
+
}
|
|
83
112
|
function registerAppVersion() {
|
|
113
|
+
failedForNetwork = false;
|
|
84
114
|
if (hasAppVersion()) {
|
|
85
115
|
apply(stored());
|
|
86
116
|
logger.Console.log(LABEL + ': reusing the ids stored for ' + state._ZAP._defaultoptions.appversion); // no i18n
|
|
@@ -117,6 +147,7 @@ function registerAppVersion() {
|
|
|
117
147
|
appversion: state._ZAP._defaultoptions.appversion,
|
|
118
148
|
identifier: state._ZAP._defaultoptions.identifier,
|
|
119
149
|
serviceUrl: state._ZAP._defaultoptions.serviceUrl,
|
|
150
|
+
zakhash: keyFingerprint(state._ZAP._defaultoptions.zak),
|
|
120
151
|
};
|
|
121
152
|
RESULT_KEYS.forEach(function (key) {
|
|
122
153
|
if (!utils.isEmpty(data[key])) {
|
|
@@ -128,6 +159,8 @@ function registerAppVersion() {
|
|
|
128
159
|
return true;
|
|
129
160
|
})
|
|
130
161
|
.catch(function (err) {
|
|
162
|
+
// a server answer carries serverResult; a request that never got one does not
|
|
163
|
+
failedForNetwork = !(err && err.serverResult) || navigator.onLine === false;
|
|
131
164
|
logger.warnAlways(LABEL + ': could not register this app version: ' + String(err && err.message ? err.message : err)); // no i18n
|
|
132
165
|
return false;
|
|
133
166
|
})
|
|
@@ -152,7 +185,9 @@ function clearAppVersion() {
|
|
|
152
185
|
storage.user_defaults.add(STORE_KEY, undefined);
|
|
153
186
|
}
|
|
154
187
|
|
|
188
|
+
exports.appVersionFailedForNetwork = appVersionFailedForNetwork;
|
|
155
189
|
exports.applyStoredAppVersion = applyStoredAppVersion;
|
|
156
190
|
exports.clearAppVersion = clearAppVersion;
|
|
157
191
|
exports.hasAppVersion = hasAppVersion;
|
|
192
|
+
exports.keyFingerprint = keyFingerprint;
|
|
158
193
|
exports.registerAppVersion = registerAppVersion;
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import type { DeviceInfo, Dict, ServerResult } from '../types.js';
|
|
2
2
|
export declare function checkAndUpdateDeviceInfo(): void;
|
|
3
3
|
export declare function addOrUpdateDeviceID(device_info: DeviceInfo, previous?: DeviceInfo): void;
|
|
4
|
+
/**
|
|
5
|
+
* Sets up this browser's device at start-up: the uuid, the device info, and a registration when
|
|
6
|
+
* the browser has none.
|
|
7
|
+
*
|
|
8
|
+
* Settings are this tab's own copy, loaded when it started. On a browser with no device yet, two
|
|
9
|
+
* tabs started together would each register it and store two devices, so the first visit runs
|
|
10
|
+
* under a lock shared by every tab of the site: the tab that gets it re-reads storage, registers
|
|
11
|
+
* only when no other tab has, and keeps the lock until the new ids are stored. The next tab then
|
|
12
|
+
* finds them. Start-up goes on as soon as the device info is set, without waiting for the server.
|
|
13
|
+
*/
|
|
14
|
+
export declare function prepareDevice(): Promise<void>;
|
|
4
15
|
/** True while the device has no server ids, so nothing can be sent yet. */
|
|
5
16
|
export declare function needsDevice(): boolean;
|
|
6
17
|
/**
|
|
@@ -17,7 +28,22 @@ export declare function getUpdatesFromServer(): Promise<Dict>;
|
|
|
17
28
|
*/
|
|
18
29
|
export declare function restoreServerSettings(): void;
|
|
19
30
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
31
|
+
* next_check_after as a time: the server's value is milliseconds, either a timestamp or a wait
|
|
32
|
+
* from now. Anything below 1e12 (2001 as a timestamp) can only be a wait.
|
|
33
|
+
*/
|
|
34
|
+
export declare function nextCheckTime(value: unknown, now: number): number;
|
|
35
|
+
/**
|
|
36
|
+
* Asks for the server settings now if the device is registered, then schedules the next ask
|
|
37
|
+
* for the time the answer gave in next_check_after. On a first visit the ids don't exist yet;
|
|
38
|
+
* registerDeviceWithApptics calls this as soon as device/add succeeds.
|
|
22
39
|
*/
|
|
23
40
|
export declare function refreshServerSettings(): void;
|
|
41
|
+
/**
|
|
42
|
+
* Start-up's getsdkconfig. Asked on a first visit and on the first page load in each tab; any
|
|
43
|
+
* other load (a reload, a link to another page of the site, back/forward) uses the saved answer
|
|
44
|
+
* and waits for its next_check_after, unless that has already passed. Nothing happens if one has
|
|
45
|
+
* gone out already on this load (after device/add).
|
|
46
|
+
*/
|
|
47
|
+
export declare function startServerSettingChecks(): void;
|
|
48
|
+
/** reset(): no more checks, and the next init() asks again straight away. */
|
|
49
|
+
export declare function stopServerSettingChecks(): void;
|