@keverdjs/fraud-sdk-angular 1.1.0 → 1.1.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/index.d.mts +29 -7
- package/dist/index.d.ts +29 -7
- package/dist/index.js +459 -21
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +459 -21
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2801,11 +2801,19 @@ var PageInteractionCollector = class {
|
|
|
2801
2801
|
};
|
|
2802
2802
|
|
|
2803
2803
|
// ../fraud-sdk/src/core/sdk.ts
|
|
2804
|
+
var DEFAULT_ENDPOINT = "https://api.keverd.com";
|
|
2804
2805
|
var KeverdSDK = class {
|
|
2806
|
+
// Maximum 10 minutes of collection
|
|
2805
2807
|
constructor() {
|
|
2806
2808
|
this.config = null;
|
|
2807
2809
|
this.isInitialized = false;
|
|
2808
2810
|
this.sessionId = null;
|
|
2811
|
+
this.ghostInterval = null;
|
|
2812
|
+
this.ghostStartTime = null;
|
|
2813
|
+
this.ghostSignalCount = 0;
|
|
2814
|
+
this.MIN_GHOST_SIGNALS = 10;
|
|
2815
|
+
// Collect at least 10 signals (5 minutes of data)
|
|
2816
|
+
this.MAX_GHOST_COLLECTION_TIME = 10 * 60 * 1e3;
|
|
2809
2817
|
this.deviceCollector = new DeviceCollector();
|
|
2810
2818
|
this.behavioralCollector = new BehavioralCollector();
|
|
2811
2819
|
this.fingerprintManager = new FingerprintManager();
|
|
@@ -2828,12 +2836,10 @@ var KeverdSDK = class {
|
|
|
2828
2836
|
if (typeof config === "string") {
|
|
2829
2837
|
this.config = {
|
|
2830
2838
|
apiKey: config,
|
|
2831
|
-
endpoint: "https://api.keverd.com",
|
|
2832
2839
|
debug: false
|
|
2833
2840
|
};
|
|
2834
2841
|
} else {
|
|
2835
2842
|
this.config = {
|
|
2836
|
-
endpoint: "https://api.keverd.com",
|
|
2837
2843
|
debug: false,
|
|
2838
2844
|
...config
|
|
2839
2845
|
};
|
|
@@ -2844,10 +2850,122 @@ var KeverdSDK = class {
|
|
|
2844
2850
|
this.sessionId = this.generateSessionId();
|
|
2845
2851
|
this.isInitialized = true;
|
|
2846
2852
|
if (this.config.debug) {
|
|
2847
|
-
console.log("[Keverd SDK] Initialized successfully"
|
|
2848
|
-
|
|
2853
|
+
console.log("[Keverd SDK] Initialized successfully");
|
|
2854
|
+
}
|
|
2855
|
+
this.startSession().catch(() => {
|
|
2856
|
+
});
|
|
2857
|
+
this.startGhostSignalCollection();
|
|
2858
|
+
}
|
|
2859
|
+
startGhostSignalCollection() {
|
|
2860
|
+
if (this.ghostInterval) return;
|
|
2861
|
+
if (!this.config) return;
|
|
2862
|
+
this.ghostStartTime = Date.now();
|
|
2863
|
+
this.ghostSignalCount = 0;
|
|
2864
|
+
const intervalMs = 3e4;
|
|
2865
|
+
const sendGhostSignal = () => {
|
|
2866
|
+
const now = Date.now();
|
|
2867
|
+
const totalCollectionTime = this.ghostStartTime ? now - this.ghostStartTime : 0;
|
|
2868
|
+
const hasEnoughSignals = this.ghostSignalCount >= this.MIN_GHOST_SIGNALS;
|
|
2869
|
+
const exceededMaxTime = totalCollectionTime >= this.MAX_GHOST_COLLECTION_TIME;
|
|
2870
|
+
if (hasEnoughSignals || exceededMaxTime) {
|
|
2871
|
+
if (this.config?.debug) {
|
|
2872
|
+
console.log(`[Keverd SDK] Ghost collection complete: ${this.ghostSignalCount} signals, ${Math.round(totalCollectionTime / 1e3)}s elapsed`);
|
|
2873
|
+
}
|
|
2874
|
+
this.stopGhostSignalCollection();
|
|
2875
|
+
return;
|
|
2876
|
+
}
|
|
2877
|
+
const durationMs = this.ghostStartTime ? now - this.ghostStartTime : intervalMs;
|
|
2878
|
+
this.sendGhostSignals(durationMs).catch((err) => {
|
|
2879
|
+
if (this.config?.debug) {
|
|
2880
|
+
console.debug("[Keverd SDK] Ghost signals upload failed:", err);
|
|
2881
|
+
}
|
|
2849
2882
|
});
|
|
2883
|
+
this.ghostSignalCount++;
|
|
2884
|
+
this.ghostStartTime = now;
|
|
2885
|
+
};
|
|
2886
|
+
setTimeout(() => {
|
|
2887
|
+
sendGhostSignal();
|
|
2888
|
+
this.ghostInterval = setInterval(() => {
|
|
2889
|
+
sendGhostSignal();
|
|
2890
|
+
}, intervalMs);
|
|
2891
|
+
}, intervalMs);
|
|
2892
|
+
}
|
|
2893
|
+
stopGhostSignalCollection() {
|
|
2894
|
+
if (this.ghostInterval) {
|
|
2895
|
+
clearInterval(this.ghostInterval);
|
|
2896
|
+
this.ghostInterval = null;
|
|
2897
|
+
this.ghostStartTime = null;
|
|
2898
|
+
}
|
|
2899
|
+
}
|
|
2900
|
+
async sendGhostSignals(durationMs) {
|
|
2901
|
+
if (!this.isInitialized || !this.config) return;
|
|
2902
|
+
const deviceInfo = this.deviceCollector.collect();
|
|
2903
|
+
const behavioralData = this.behavioralCollector.getData();
|
|
2904
|
+
const fingerprintData = await this.fingerprintManager.collect();
|
|
2905
|
+
const fingerprintjsData = {
|
|
2906
|
+
visitorId: fingerprintData.visitorId,
|
|
2907
|
+
confidence: fingerprintData.confidence,
|
|
2908
|
+
components: fingerprintData.components
|
|
2909
|
+
};
|
|
2910
|
+
const privacySignals = this.privacySignalCollector.collect();
|
|
2911
|
+
const browserCapabilities = this.browserCapabilityCollector.collect();
|
|
2912
|
+
const hardwareSignals = this.hardwareSignalCollector.collect();
|
|
2913
|
+
const formInteractions = this.formInteractionCollector.getData();
|
|
2914
|
+
const mouseSignals = this.behavioralCollector.getMouseSignals();
|
|
2915
|
+
const keyboardSignals = this.behavioralCollector.getKeyboardSignals();
|
|
2916
|
+
const pageInteractions = this.pageInteractionCollector.getData();
|
|
2917
|
+
const networkSignals = {
|
|
2918
|
+
connectionType: hardwareSignals.connectionType || void 0,
|
|
2919
|
+
effectiveType: hardwareSignals.effectiveType || void 0,
|
|
2920
|
+
downlink: hardwareSignals.downlink || void 0,
|
|
2921
|
+
rtt: hardwareSignals.rtt || void 0,
|
|
2922
|
+
saveData: hardwareSignals.saveData || void 0
|
|
2923
|
+
};
|
|
2924
|
+
const sessionInfo = {
|
|
2925
|
+
sessionId: this.sessionId || void 0,
|
|
2926
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2927
|
+
};
|
|
2928
|
+
const request = {
|
|
2929
|
+
userId: this.config.userId,
|
|
2930
|
+
device: deviceInfo,
|
|
2931
|
+
session: sessionInfo,
|
|
2932
|
+
behavioral: behavioralData,
|
|
2933
|
+
duration_ms: durationMs,
|
|
2934
|
+
fingerprintjs: fingerprintjsData || void 0,
|
|
2935
|
+
privacySignals,
|
|
2936
|
+
browserCapabilities,
|
|
2937
|
+
hardwareSignals,
|
|
2938
|
+
formInteractions,
|
|
2939
|
+
mouseSignals,
|
|
2940
|
+
keyboardSignals,
|
|
2941
|
+
pageInteractions,
|
|
2942
|
+
networkSignals,
|
|
2943
|
+
useCase: "ghost"
|
|
2944
|
+
};
|
|
2945
|
+
const url = `${DEFAULT_ENDPOINT}/fingerprint/ghost`;
|
|
2946
|
+
const headers = {
|
|
2947
|
+
"Content-Type": "application/json",
|
|
2948
|
+
"X-SDK-Source": "javascript"
|
|
2949
|
+
};
|
|
2950
|
+
const { origin, referrer } = this.getOriginHeaders();
|
|
2951
|
+
if (origin) {
|
|
2952
|
+
headers["X-Origin-URL"] = origin;
|
|
2953
|
+
}
|
|
2954
|
+
if (referrer) {
|
|
2955
|
+
headers["X-Referrer-URL"] = referrer;
|
|
2956
|
+
}
|
|
2957
|
+
const apiKey = this.config.apiKey;
|
|
2958
|
+
if (apiKey) {
|
|
2959
|
+
headers["x-keverd-key"] = apiKey;
|
|
2960
|
+
headers["X-API-KEY"] = apiKey;
|
|
2961
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
2850
2962
|
}
|
|
2963
|
+
await fetch(url, {
|
|
2964
|
+
method: "POST",
|
|
2965
|
+
headers,
|
|
2966
|
+
body: JSON.stringify(request)
|
|
2967
|
+
}).catch(() => {
|
|
2968
|
+
});
|
|
2851
2969
|
}
|
|
2852
2970
|
/**
|
|
2853
2971
|
* Get visitor data (fingerprint and risk assessment)
|
|
@@ -3033,12 +3151,18 @@ var KeverdSDK = class {
|
|
|
3033
3151
|
if (options.changeType) {
|
|
3034
3152
|
request.changeType = options.changeType;
|
|
3035
3153
|
}
|
|
3036
|
-
const
|
|
3037
|
-
const url = `${endpoint}/fingerprint/verify/${useCase}`;
|
|
3154
|
+
const url = `${DEFAULT_ENDPOINT}/fingerprint/verify/${useCase}`;
|
|
3038
3155
|
const headers = {
|
|
3039
3156
|
"Content-Type": "application/json",
|
|
3040
3157
|
"X-SDK-Source": "javascript"
|
|
3041
3158
|
};
|
|
3159
|
+
const { origin, referrer } = this.getOriginHeaders();
|
|
3160
|
+
if (origin) {
|
|
3161
|
+
headers["X-Origin-URL"] = origin;
|
|
3162
|
+
}
|
|
3163
|
+
if (referrer) {
|
|
3164
|
+
headers["X-Referrer-URL"] = referrer;
|
|
3165
|
+
}
|
|
3042
3166
|
const apiKey = this.config.apiKey;
|
|
3043
3167
|
if (apiKey) {
|
|
3044
3168
|
headers["x-keverd-key"] = apiKey;
|
|
@@ -3057,6 +3181,17 @@ var KeverdSDK = class {
|
|
|
3057
3181
|
const data = await response.json();
|
|
3058
3182
|
return data;
|
|
3059
3183
|
}
|
|
3184
|
+
/**
|
|
3185
|
+
* Extract origin and referrer from browser
|
|
3186
|
+
*/
|
|
3187
|
+
getOriginHeaders() {
|
|
3188
|
+
if (typeof window === "undefined") {
|
|
3189
|
+
return {};
|
|
3190
|
+
}
|
|
3191
|
+
const origin = window.location.origin || void 0;
|
|
3192
|
+
const referrer = document.referrer || void 0;
|
|
3193
|
+
return { origin, referrer };
|
|
3194
|
+
}
|
|
3060
3195
|
/**
|
|
3061
3196
|
* Send fingerprint request to backend
|
|
3062
3197
|
*/
|
|
@@ -3064,13 +3199,19 @@ var KeverdSDK = class {
|
|
|
3064
3199
|
if (!this.config) {
|
|
3065
3200
|
throw new Error("SDK not initialized");
|
|
3066
3201
|
}
|
|
3067
|
-
const
|
|
3068
|
-
const url = `${endpoint}/fingerprint/score`;
|
|
3202
|
+
const url = `${DEFAULT_ENDPOINT}/fingerprint/score`;
|
|
3069
3203
|
const headers = {
|
|
3070
3204
|
"Content-Type": "application/json",
|
|
3071
3205
|
"X-SDK-Source": "javascript"
|
|
3072
3206
|
// Identify SDK source for backend analytics
|
|
3073
3207
|
};
|
|
3208
|
+
const { origin, referrer } = this.getOriginHeaders();
|
|
3209
|
+
if (origin) {
|
|
3210
|
+
headers["X-Origin-URL"] = origin;
|
|
3211
|
+
}
|
|
3212
|
+
if (referrer) {
|
|
3213
|
+
headers["X-Referrer-URL"] = referrer;
|
|
3214
|
+
}
|
|
3074
3215
|
const apiKey = this.config.apiKey;
|
|
3075
3216
|
if (apiKey) {
|
|
3076
3217
|
headers["x-keverd-key"] = apiKey;
|
|
@@ -3095,15 +3236,222 @@ var KeverdSDK = class {
|
|
|
3095
3236
|
generateSessionId() {
|
|
3096
3237
|
return `${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
3097
3238
|
}
|
|
3239
|
+
/**
|
|
3240
|
+
* Detect browser name from user agent
|
|
3241
|
+
*/
|
|
3242
|
+
_detectBrowser() {
|
|
3243
|
+
const ua = navigator.userAgent;
|
|
3244
|
+
if (ua.includes("Chrome")) return "Chrome";
|
|
3245
|
+
if (ua.includes("Firefox")) return "Firefox";
|
|
3246
|
+
if (ua.includes("Safari") && !ua.includes("Chrome")) return "Safari";
|
|
3247
|
+
if (ua.includes("Edge")) return "Edge";
|
|
3248
|
+
if (ua.includes("Opera")) return "Opera";
|
|
3249
|
+
return void 0;
|
|
3250
|
+
}
|
|
3251
|
+
/**
|
|
3252
|
+
* Detect OS from user agent
|
|
3253
|
+
*/
|
|
3254
|
+
_detectOS() {
|
|
3255
|
+
const ua = navigator.userAgent;
|
|
3256
|
+
if (ua.includes("Windows")) return "Windows";
|
|
3257
|
+
if (ua.includes("Mac OS")) return "macOS";
|
|
3258
|
+
if (ua.includes("Linux")) return "Linux";
|
|
3259
|
+
if (ua.includes("Android")) return "Android";
|
|
3260
|
+
if (ua.includes("iOS") || ua.includes("iPhone") || ua.includes("iPad")) return "iOS";
|
|
3261
|
+
return void 0;
|
|
3262
|
+
}
|
|
3263
|
+
/**
|
|
3264
|
+
* Start a new session (called automatically on init, but can be called manually)
|
|
3265
|
+
*/
|
|
3266
|
+
async startSession(userId, deviceHash, metadata) {
|
|
3267
|
+
if (!this.isInitialized || !this.config) {
|
|
3268
|
+
throw new Error("Keverd SDK not initialized. Call init() first.");
|
|
3269
|
+
}
|
|
3270
|
+
if (!this.sessionId) {
|
|
3271
|
+
this.sessionId = this.generateSessionId();
|
|
3272
|
+
}
|
|
3273
|
+
try {
|
|
3274
|
+
const url = `${DEFAULT_ENDPOINT}/dashboard/sessions/start`;
|
|
3275
|
+
const headers = {
|
|
3276
|
+
"Content-Type": "application/json"
|
|
3277
|
+
};
|
|
3278
|
+
const { origin, referrer } = this.getOriginHeaders();
|
|
3279
|
+
if (origin) {
|
|
3280
|
+
headers["X-Origin-URL"] = origin;
|
|
3281
|
+
}
|
|
3282
|
+
if (referrer) {
|
|
3283
|
+
headers["X-Referrer-URL"] = referrer;
|
|
3284
|
+
}
|
|
3285
|
+
const apiKey = this.config.apiKey;
|
|
3286
|
+
if (apiKey) {
|
|
3287
|
+
headers["x-keverd-key"] = apiKey;
|
|
3288
|
+
headers["X-API-KEY"] = apiKey;
|
|
3289
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
3290
|
+
}
|
|
3291
|
+
const deviceInfo = this.deviceCollector.collect();
|
|
3292
|
+
await fetch(url, {
|
|
3293
|
+
method: "POST",
|
|
3294
|
+
headers,
|
|
3295
|
+
body: JSON.stringify({
|
|
3296
|
+
session_id: this.sessionId,
|
|
3297
|
+
user_id: userId || this.config.userId,
|
|
3298
|
+
device_hash: deviceHash || deviceInfo.fingerprint,
|
|
3299
|
+
metadata: metadata || {},
|
|
3300
|
+
user_agent: navigator.userAgent,
|
|
3301
|
+
browser: this._detectBrowser(),
|
|
3302
|
+
os: this._detectOS(),
|
|
3303
|
+
platform: "web",
|
|
3304
|
+
sdk_type: "web",
|
|
3305
|
+
sdk_source: "javascript"
|
|
3306
|
+
})
|
|
3307
|
+
});
|
|
3308
|
+
if (this.config.debug) {
|
|
3309
|
+
console.log(`[Keverd SDK] Session started: ${this.sessionId}`);
|
|
3310
|
+
}
|
|
3311
|
+
} catch (error) {
|
|
3312
|
+
if (this.config.debug) {
|
|
3313
|
+
console.warn("[Keverd SDK] Failed to start session on server:", error);
|
|
3314
|
+
}
|
|
3315
|
+
}
|
|
3316
|
+
}
|
|
3317
|
+
/**
|
|
3318
|
+
* End the current session
|
|
3319
|
+
*/
|
|
3320
|
+
async endSession() {
|
|
3321
|
+
if (!this.isInitialized || !this.config || !this.sessionId) {
|
|
3322
|
+
return;
|
|
3323
|
+
}
|
|
3324
|
+
try {
|
|
3325
|
+
const url = `${DEFAULT_ENDPOINT}/dashboard/sessions/${this.sessionId}/end`;
|
|
3326
|
+
const headers = {
|
|
3327
|
+
"Content-Type": "application/json"
|
|
3328
|
+
};
|
|
3329
|
+
const apiKey = this.config.apiKey;
|
|
3330
|
+
if (apiKey) {
|
|
3331
|
+
headers["x-keverd-key"] = apiKey;
|
|
3332
|
+
headers["X-API-KEY"] = apiKey;
|
|
3333
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
3334
|
+
}
|
|
3335
|
+
await fetch(url, {
|
|
3336
|
+
method: "POST",
|
|
3337
|
+
headers
|
|
3338
|
+
});
|
|
3339
|
+
if (this.config.debug) {
|
|
3340
|
+
console.log(`[Keverd SDK] Session ended: ${this.sessionId}`);
|
|
3341
|
+
}
|
|
3342
|
+
} catch (error) {
|
|
3343
|
+
if (this.config.debug) {
|
|
3344
|
+
console.warn("[Keverd SDK] Failed to end session on server:", error);
|
|
3345
|
+
}
|
|
3346
|
+
}
|
|
3347
|
+
}
|
|
3348
|
+
/**
|
|
3349
|
+
* Pause the current session (e.g., when app goes to background)
|
|
3350
|
+
*/
|
|
3351
|
+
async pauseSession() {
|
|
3352
|
+
if (!this.isInitialized || !this.config || !this.sessionId) {
|
|
3353
|
+
return;
|
|
3354
|
+
}
|
|
3355
|
+
try {
|
|
3356
|
+
const url = `${DEFAULT_ENDPOINT}/dashboard/sessions/${this.sessionId}/pause`;
|
|
3357
|
+
const headers = {
|
|
3358
|
+
"Content-Type": "application/json"
|
|
3359
|
+
};
|
|
3360
|
+
const apiKey = this.config.apiKey;
|
|
3361
|
+
if (apiKey) {
|
|
3362
|
+
headers["x-keverd-key"] = apiKey;
|
|
3363
|
+
headers["X-API-KEY"] = apiKey;
|
|
3364
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
3365
|
+
}
|
|
3366
|
+
await fetch(url, {
|
|
3367
|
+
method: "POST",
|
|
3368
|
+
headers
|
|
3369
|
+
});
|
|
3370
|
+
if (this.config.debug) {
|
|
3371
|
+
console.log(`[Keverd SDK] Session paused: ${this.sessionId}`);
|
|
3372
|
+
}
|
|
3373
|
+
} catch (error) {
|
|
3374
|
+
if (this.config.debug) {
|
|
3375
|
+
console.warn("[Keverd SDK] Failed to pause session on server:", error);
|
|
3376
|
+
}
|
|
3377
|
+
}
|
|
3378
|
+
}
|
|
3379
|
+
/**
|
|
3380
|
+
* Resume a paused session (e.g., when app comes to foreground)
|
|
3381
|
+
*/
|
|
3382
|
+
async resumeSession() {
|
|
3383
|
+
if (!this.isInitialized || !this.config || !this.sessionId) {
|
|
3384
|
+
return;
|
|
3385
|
+
}
|
|
3386
|
+
try {
|
|
3387
|
+
const url = `${DEFAULT_ENDPOINT}/dashboard/sessions/${this.sessionId}/resume`;
|
|
3388
|
+
const headers = {
|
|
3389
|
+
"Content-Type": "application/json"
|
|
3390
|
+
};
|
|
3391
|
+
const apiKey = this.config.apiKey;
|
|
3392
|
+
if (apiKey) {
|
|
3393
|
+
headers["x-keverd-key"] = apiKey;
|
|
3394
|
+
headers["X-API-KEY"] = apiKey;
|
|
3395
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
3396
|
+
}
|
|
3397
|
+
await fetch(url, {
|
|
3398
|
+
method: "POST",
|
|
3399
|
+
headers
|
|
3400
|
+
});
|
|
3401
|
+
if (this.config.debug) {
|
|
3402
|
+
console.log(`[Keverd SDK] Session resumed: ${this.sessionId}`);
|
|
3403
|
+
}
|
|
3404
|
+
} catch (error) {
|
|
3405
|
+
if (this.config.debug) {
|
|
3406
|
+
console.warn("[Keverd SDK] Failed to resume session on server:", error);
|
|
3407
|
+
}
|
|
3408
|
+
}
|
|
3409
|
+
}
|
|
3410
|
+
/**
|
|
3411
|
+
* Get current session status
|
|
3412
|
+
*/
|
|
3413
|
+
async getSessionStatus() {
|
|
3414
|
+
if (!this.isInitialized || !this.config || !this.sessionId) {
|
|
3415
|
+
return null;
|
|
3416
|
+
}
|
|
3417
|
+
try {
|
|
3418
|
+
const url = `${DEFAULT_ENDPOINT}/dashboard/sessions/${this.sessionId}/status`;
|
|
3419
|
+
const headers = {};
|
|
3420
|
+
const apiKey = this.config.apiKey;
|
|
3421
|
+
if (apiKey) {
|
|
3422
|
+
headers["x-keverd-key"] = apiKey;
|
|
3423
|
+
headers["X-API-KEY"] = apiKey;
|
|
3424
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
3425
|
+
}
|
|
3426
|
+
const response = await fetch(url, {
|
|
3427
|
+
method: "GET",
|
|
3428
|
+
headers
|
|
3429
|
+
});
|
|
3430
|
+
if (!response.ok) {
|
|
3431
|
+
return null;
|
|
3432
|
+
}
|
|
3433
|
+
return await response.json();
|
|
3434
|
+
} catch (error) {
|
|
3435
|
+
if (this.config.debug) {
|
|
3436
|
+
console.warn("[Keverd SDK] Failed to get session status:", error);
|
|
3437
|
+
}
|
|
3438
|
+
return null;
|
|
3439
|
+
}
|
|
3440
|
+
}
|
|
3098
3441
|
/**
|
|
3099
3442
|
* Destroy the SDK instance
|
|
3100
3443
|
*/
|
|
3101
|
-
destroy() {
|
|
3444
|
+
async destroy() {
|
|
3445
|
+
if (this.sessionId) {
|
|
3446
|
+
await this.endSession();
|
|
3447
|
+
}
|
|
3102
3448
|
this.behavioralCollector.stop();
|
|
3103
3449
|
this.formInteractionCollector.stop();
|
|
3104
3450
|
this.pageInteractionCollector.stop();
|
|
3105
3451
|
this.fingerprintManager.clearCache();
|
|
3106
3452
|
this.isInitialized = false;
|
|
3453
|
+
this.stopGhostSignalCollection();
|
|
3454
|
+
this.ghostSignalCount = 0;
|
|
3107
3455
|
if (this.config?.debug) {
|
|
3108
3456
|
console.log("[Keverd SDK] Destroyed");
|
|
3109
3457
|
}
|
|
@@ -3143,22 +3491,20 @@ var KeverdService = class {
|
|
|
3143
3491
|
throw new Error("Keverd SDK: apiKey is required");
|
|
3144
3492
|
}
|
|
3145
3493
|
this.config = {
|
|
3146
|
-
endpoint: config.endpoint || this.getDefaultEndpoint(),
|
|
3147
3494
|
debug: false,
|
|
3148
3495
|
...config
|
|
3149
3496
|
};
|
|
3150
3497
|
Keverd.init({
|
|
3151
3498
|
apiKey: this.config.apiKey,
|
|
3152
|
-
endpoint: this.config.endpoint,
|
|
3153
3499
|
userId: this.config.userId,
|
|
3154
3500
|
debug: this.config.debug || false
|
|
3155
3501
|
});
|
|
3156
3502
|
this.isInitialized = true;
|
|
3157
3503
|
if (this.config.debug) {
|
|
3158
|
-
console.log("[Keverd SDK] Initialized successfully"
|
|
3159
|
-
endpoint: this.config.endpoint
|
|
3160
|
-
});
|
|
3504
|
+
console.log("[Keverd SDK] Initialized successfully");
|
|
3161
3505
|
}
|
|
3506
|
+
Keverd.startSession().catch(() => {
|
|
3507
|
+
});
|
|
3162
3508
|
}
|
|
3163
3509
|
/**
|
|
3164
3510
|
* Get visitor data (fingerprint and risk assessment)
|
|
@@ -3223,22 +3569,115 @@ var KeverdService = class {
|
|
|
3223
3569
|
recommendedAction: response.recommended_action
|
|
3224
3570
|
};
|
|
3225
3571
|
}
|
|
3226
|
-
/**
|
|
3227
|
-
* Get default endpoint
|
|
3228
|
-
*/
|
|
3229
|
-
getDefaultEndpoint() {
|
|
3230
|
-
return "https://api.keverd.com";
|
|
3231
|
-
}
|
|
3232
3572
|
/**
|
|
3233
3573
|
* Generate a session ID
|
|
3234
3574
|
*/
|
|
3235
3575
|
generateSessionId() {
|
|
3236
3576
|
return `${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
3237
3577
|
}
|
|
3578
|
+
/**
|
|
3579
|
+
* Start a new session (called automatically on init, but can be called manually)
|
|
3580
|
+
*/
|
|
3581
|
+
startSession(userId, deviceHash, metadata) {
|
|
3582
|
+
if (!this.isInitialized || !this.config) {
|
|
3583
|
+
return throwError(() => ({
|
|
3584
|
+
message: "Keverd SDK not initialized. Call init() first.",
|
|
3585
|
+
code: "SDK_NOT_INITIALIZED"
|
|
3586
|
+
}));
|
|
3587
|
+
}
|
|
3588
|
+
return from(Keverd.startSession(userId, deviceHash, metadata)).pipe(
|
|
3589
|
+
catchError((error) => {
|
|
3590
|
+
if (this.config?.debug) {
|
|
3591
|
+
console.warn("[Keverd SDK] Failed to start session:", error);
|
|
3592
|
+
}
|
|
3593
|
+
return throwError(() => error);
|
|
3594
|
+
})
|
|
3595
|
+
);
|
|
3596
|
+
}
|
|
3597
|
+
/**
|
|
3598
|
+
* End the current session
|
|
3599
|
+
*/
|
|
3600
|
+
endSession() {
|
|
3601
|
+
if (!this.isInitialized || !this.config) {
|
|
3602
|
+
return throwError(() => ({
|
|
3603
|
+
message: "Keverd SDK not initialized. Call init() first.",
|
|
3604
|
+
code: "SDK_NOT_INITIALIZED"
|
|
3605
|
+
}));
|
|
3606
|
+
}
|
|
3607
|
+
return from(Keverd.endSession()).pipe(
|
|
3608
|
+
catchError((error) => {
|
|
3609
|
+
if (this.config?.debug) {
|
|
3610
|
+
console.warn("[Keverd SDK] Failed to end session:", error);
|
|
3611
|
+
}
|
|
3612
|
+
return throwError(() => error);
|
|
3613
|
+
})
|
|
3614
|
+
);
|
|
3615
|
+
}
|
|
3616
|
+
/**
|
|
3617
|
+
* Pause the current session (e.g., when app goes to background)
|
|
3618
|
+
*/
|
|
3619
|
+
pauseSession() {
|
|
3620
|
+
if (!this.isInitialized || !this.config) {
|
|
3621
|
+
return throwError(() => ({
|
|
3622
|
+
message: "Keverd SDK not initialized. Call init() first.",
|
|
3623
|
+
code: "SDK_NOT_INITIALIZED"
|
|
3624
|
+
}));
|
|
3625
|
+
}
|
|
3626
|
+
return from(Keverd.pauseSession()).pipe(
|
|
3627
|
+
catchError((error) => {
|
|
3628
|
+
if (this.config?.debug) {
|
|
3629
|
+
console.warn("[Keverd SDK] Failed to pause session:", error);
|
|
3630
|
+
}
|
|
3631
|
+
return throwError(() => error);
|
|
3632
|
+
})
|
|
3633
|
+
);
|
|
3634
|
+
}
|
|
3635
|
+
/**
|
|
3636
|
+
* Resume a paused session (e.g., when app comes to foreground)
|
|
3637
|
+
*/
|
|
3638
|
+
resumeSession() {
|
|
3639
|
+
if (!this.isInitialized || !this.config) {
|
|
3640
|
+
return throwError(() => ({
|
|
3641
|
+
message: "Keverd SDK not initialized. Call init() first.",
|
|
3642
|
+
code: "SDK_NOT_INITIALIZED"
|
|
3643
|
+
}));
|
|
3644
|
+
}
|
|
3645
|
+
return from(Keverd.resumeSession()).pipe(
|
|
3646
|
+
catchError((error) => {
|
|
3647
|
+
if (this.config?.debug) {
|
|
3648
|
+
console.warn("[Keverd SDK] Failed to resume session:", error);
|
|
3649
|
+
}
|
|
3650
|
+
return throwError(() => error);
|
|
3651
|
+
})
|
|
3652
|
+
);
|
|
3653
|
+
}
|
|
3654
|
+
/**
|
|
3655
|
+
* Get current session status
|
|
3656
|
+
*/
|
|
3657
|
+
getSessionStatus() {
|
|
3658
|
+
if (!this.isInitialized || !this.config) {
|
|
3659
|
+
return throwError(() => ({
|
|
3660
|
+
message: "Keverd SDK not initialized. Call init() first.",
|
|
3661
|
+
code: "SDK_NOT_INITIALIZED"
|
|
3662
|
+
}));
|
|
3663
|
+
}
|
|
3664
|
+
return from(Keverd.getSessionStatus()).pipe(
|
|
3665
|
+
catchError((error) => {
|
|
3666
|
+
if (this.config?.debug) {
|
|
3667
|
+
console.warn("[Keverd SDK] Failed to get session status:", error);
|
|
3668
|
+
}
|
|
3669
|
+
return throwError(() => error);
|
|
3670
|
+
})
|
|
3671
|
+
);
|
|
3672
|
+
}
|
|
3238
3673
|
/**
|
|
3239
3674
|
* Destroy the SDK instance
|
|
3240
3675
|
*/
|
|
3241
3676
|
destroy() {
|
|
3677
|
+
if (this.isInitialized) {
|
|
3678
|
+
Keverd.endSession().catch(() => {
|
|
3679
|
+
});
|
|
3680
|
+
}
|
|
3242
3681
|
Keverd.destroy();
|
|
3243
3682
|
this.isInitialized = false;
|
|
3244
3683
|
this.config = null;
|
|
@@ -3274,7 +3713,6 @@ var KeverdModule = class {
|
|
|
3274
3713
|
* imports: [
|
|
3275
3714
|
* KeverdModule.forRoot({
|
|
3276
3715
|
* apiKey: 'your-api-key',
|
|
3277
|
-
* endpoint: 'https://api.keverd.com'
|
|
3278
3716
|
* })
|
|
3279
3717
|
* ]
|
|
3280
3718
|
* })
|