@keverdjs/fraud-sdk-angular 1.1.0 → 2.0.0
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 +420 -21
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +420 -21
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -93,7 +93,6 @@ interface KeverdVisitorData {
|
|
|
93
93
|
}
|
|
94
94
|
interface KeverdConfig {
|
|
95
95
|
apiKey: string;
|
|
96
|
-
endpoint?: string;
|
|
97
96
|
userId?: string;
|
|
98
97
|
debug?: boolean;
|
|
99
98
|
extendedResult?: boolean;
|
|
@@ -101,7 +100,6 @@ interface KeverdConfig {
|
|
|
101
100
|
}
|
|
102
101
|
interface KeverdLoadOptions {
|
|
103
102
|
apiKey: string;
|
|
104
|
-
endpoint?: string;
|
|
105
103
|
debug?: boolean;
|
|
106
104
|
}
|
|
107
105
|
interface KeverdVisitorDataOptions {
|
|
@@ -144,14 +142,39 @@ declare class KeverdService {
|
|
|
144
142
|
* Transform API response to visitor data format
|
|
145
143
|
*/
|
|
146
144
|
private transformResponse;
|
|
147
|
-
/**
|
|
148
|
-
* Get default endpoint
|
|
149
|
-
*/
|
|
150
|
-
private getDefaultEndpoint;
|
|
151
145
|
/**
|
|
152
146
|
* Generate a session ID
|
|
153
147
|
*/
|
|
154
148
|
private generateSessionId;
|
|
149
|
+
/**
|
|
150
|
+
* Start a new session (called automatically on init, but can be called manually)
|
|
151
|
+
*/
|
|
152
|
+
startSession(userId?: string, deviceHash?: string, metadata?: Record<string, unknown>): Observable<void>;
|
|
153
|
+
/**
|
|
154
|
+
* End the current session
|
|
155
|
+
*/
|
|
156
|
+
endSession(): Observable<void>;
|
|
157
|
+
/**
|
|
158
|
+
* Pause the current session (e.g., when app goes to background)
|
|
159
|
+
*/
|
|
160
|
+
pauseSession(): Observable<void>;
|
|
161
|
+
/**
|
|
162
|
+
* Resume a paused session (e.g., when app comes to foreground)
|
|
163
|
+
*/
|
|
164
|
+
resumeSession(): Observable<void>;
|
|
165
|
+
/**
|
|
166
|
+
* Get current session status
|
|
167
|
+
*/
|
|
168
|
+
getSessionStatus(): Observable<{
|
|
169
|
+
session_id: string;
|
|
170
|
+
status: string;
|
|
171
|
+
is_active: boolean;
|
|
172
|
+
is_paused: boolean;
|
|
173
|
+
event_count: number;
|
|
174
|
+
started_at: string;
|
|
175
|
+
last_activity_at: string;
|
|
176
|
+
duration_seconds: number | null;
|
|
177
|
+
} | null>;
|
|
155
178
|
/**
|
|
156
179
|
* Destroy the SDK instance
|
|
157
180
|
*/
|
|
@@ -182,7 +205,6 @@ declare class KeverdModule {
|
|
|
182
205
|
* imports: [
|
|
183
206
|
* KeverdModule.forRoot({
|
|
184
207
|
* apiKey: 'your-api-key',
|
|
185
|
-
* endpoint: 'https://api.keverd.com'
|
|
186
208
|
* })
|
|
187
209
|
* ]
|
|
188
210
|
* })
|
package/dist/index.d.ts
CHANGED
|
@@ -93,7 +93,6 @@ interface KeverdVisitorData {
|
|
|
93
93
|
}
|
|
94
94
|
interface KeverdConfig {
|
|
95
95
|
apiKey: string;
|
|
96
|
-
endpoint?: string;
|
|
97
96
|
userId?: string;
|
|
98
97
|
debug?: boolean;
|
|
99
98
|
extendedResult?: boolean;
|
|
@@ -101,7 +100,6 @@ interface KeverdConfig {
|
|
|
101
100
|
}
|
|
102
101
|
interface KeverdLoadOptions {
|
|
103
102
|
apiKey: string;
|
|
104
|
-
endpoint?: string;
|
|
105
103
|
debug?: boolean;
|
|
106
104
|
}
|
|
107
105
|
interface KeverdVisitorDataOptions {
|
|
@@ -144,14 +142,39 @@ declare class KeverdService {
|
|
|
144
142
|
* Transform API response to visitor data format
|
|
145
143
|
*/
|
|
146
144
|
private transformResponse;
|
|
147
|
-
/**
|
|
148
|
-
* Get default endpoint
|
|
149
|
-
*/
|
|
150
|
-
private getDefaultEndpoint;
|
|
151
145
|
/**
|
|
152
146
|
* Generate a session ID
|
|
153
147
|
*/
|
|
154
148
|
private generateSessionId;
|
|
149
|
+
/**
|
|
150
|
+
* Start a new session (called automatically on init, but can be called manually)
|
|
151
|
+
*/
|
|
152
|
+
startSession(userId?: string, deviceHash?: string, metadata?: Record<string, unknown>): Observable<void>;
|
|
153
|
+
/**
|
|
154
|
+
* End the current session
|
|
155
|
+
*/
|
|
156
|
+
endSession(): Observable<void>;
|
|
157
|
+
/**
|
|
158
|
+
* Pause the current session (e.g., when app goes to background)
|
|
159
|
+
*/
|
|
160
|
+
pauseSession(): Observable<void>;
|
|
161
|
+
/**
|
|
162
|
+
* Resume a paused session (e.g., when app comes to foreground)
|
|
163
|
+
*/
|
|
164
|
+
resumeSession(): Observable<void>;
|
|
165
|
+
/**
|
|
166
|
+
* Get current session status
|
|
167
|
+
*/
|
|
168
|
+
getSessionStatus(): Observable<{
|
|
169
|
+
session_id: string;
|
|
170
|
+
status: string;
|
|
171
|
+
is_active: boolean;
|
|
172
|
+
is_paused: boolean;
|
|
173
|
+
event_count: number;
|
|
174
|
+
started_at: string;
|
|
175
|
+
last_activity_at: string;
|
|
176
|
+
duration_seconds: number | null;
|
|
177
|
+
} | null>;
|
|
155
178
|
/**
|
|
156
179
|
* Destroy the SDK instance
|
|
157
180
|
*/
|
|
@@ -182,7 +205,6 @@ declare class KeverdModule {
|
|
|
182
205
|
* imports: [
|
|
183
206
|
* KeverdModule.forRoot({
|
|
184
207
|
* apiKey: 'your-api-key',
|
|
185
|
-
* endpoint: 'https://api.keverd.com'
|
|
186
208
|
* })
|
|
187
209
|
* ]
|
|
188
210
|
* })
|
package/dist/index.js
CHANGED
|
@@ -2803,11 +2803,19 @@ var PageInteractionCollector = class {
|
|
|
2803
2803
|
};
|
|
2804
2804
|
|
|
2805
2805
|
// ../fraud-sdk/src/core/sdk.ts
|
|
2806
|
+
var DEFAULT_ENDPOINT = "https://api.keverd.com";
|
|
2806
2807
|
var KeverdSDK = class {
|
|
2808
|
+
// Maximum 10 minutes of collection
|
|
2807
2809
|
constructor() {
|
|
2808
2810
|
this.config = null;
|
|
2809
2811
|
this.isInitialized = false;
|
|
2810
2812
|
this.sessionId = null;
|
|
2813
|
+
this.ghostInterval = null;
|
|
2814
|
+
this.ghostStartTime = null;
|
|
2815
|
+
this.ghostSignalCount = 0;
|
|
2816
|
+
this.MIN_GHOST_SIGNALS = 10;
|
|
2817
|
+
// Collect at least 10 signals (5 minutes of data)
|
|
2818
|
+
this.MAX_GHOST_COLLECTION_TIME = 10 * 60 * 1e3;
|
|
2811
2819
|
this.deviceCollector = new DeviceCollector();
|
|
2812
2820
|
this.behavioralCollector = new BehavioralCollector();
|
|
2813
2821
|
this.fingerprintManager = new FingerprintManager();
|
|
@@ -2830,12 +2838,10 @@ var KeverdSDK = class {
|
|
|
2830
2838
|
if (typeof config === "string") {
|
|
2831
2839
|
this.config = {
|
|
2832
2840
|
apiKey: config,
|
|
2833
|
-
endpoint: "https://api.keverd.com",
|
|
2834
2841
|
debug: false
|
|
2835
2842
|
};
|
|
2836
2843
|
} else {
|
|
2837
2844
|
this.config = {
|
|
2838
|
-
endpoint: "https://api.keverd.com",
|
|
2839
2845
|
debug: false,
|
|
2840
2846
|
...config
|
|
2841
2847
|
};
|
|
@@ -2846,10 +2852,115 @@ var KeverdSDK = class {
|
|
|
2846
2852
|
this.sessionId = this.generateSessionId();
|
|
2847
2853
|
this.isInitialized = true;
|
|
2848
2854
|
if (this.config.debug) {
|
|
2849
|
-
console.log("[Keverd SDK] Initialized successfully"
|
|
2850
|
-
|
|
2855
|
+
console.log("[Keverd SDK] Initialized successfully");
|
|
2856
|
+
}
|
|
2857
|
+
this.startSession().catch(() => {
|
|
2858
|
+
});
|
|
2859
|
+
this.startGhostSignalCollection();
|
|
2860
|
+
}
|
|
2861
|
+
startGhostSignalCollection() {
|
|
2862
|
+
if (this.ghostInterval) return;
|
|
2863
|
+
if (!this.config) return;
|
|
2864
|
+
this.ghostStartTime = Date.now();
|
|
2865
|
+
this.ghostSignalCount = 0;
|
|
2866
|
+
const intervalMs = 3e4;
|
|
2867
|
+
const sendGhostSignal = () => {
|
|
2868
|
+
const now = Date.now();
|
|
2869
|
+
const totalCollectionTime = this.ghostStartTime ? now - this.ghostStartTime : 0;
|
|
2870
|
+
const hasEnoughSignals = this.ghostSignalCount >= this.MIN_GHOST_SIGNALS;
|
|
2871
|
+
const exceededMaxTime = totalCollectionTime >= this.MAX_GHOST_COLLECTION_TIME;
|
|
2872
|
+
if (hasEnoughSignals || exceededMaxTime) {
|
|
2873
|
+
if (this.config?.debug) {
|
|
2874
|
+
console.log(`[Keverd SDK] Ghost collection complete: ${this.ghostSignalCount} signals, ${Math.round(totalCollectionTime / 1e3)}s elapsed`);
|
|
2875
|
+
}
|
|
2876
|
+
this.stopGhostSignalCollection();
|
|
2877
|
+
return;
|
|
2878
|
+
}
|
|
2879
|
+
const durationMs = this.ghostStartTime ? now - this.ghostStartTime : intervalMs;
|
|
2880
|
+
this.sendGhostSignals(durationMs).catch((err) => {
|
|
2881
|
+
if (this.config?.debug) {
|
|
2882
|
+
console.debug("[Keverd SDK] Ghost signals upload failed:", err);
|
|
2883
|
+
}
|
|
2851
2884
|
});
|
|
2885
|
+
this.ghostSignalCount++;
|
|
2886
|
+
this.ghostStartTime = now;
|
|
2887
|
+
};
|
|
2888
|
+
setTimeout(() => {
|
|
2889
|
+
sendGhostSignal();
|
|
2890
|
+
this.ghostInterval = setInterval(() => {
|
|
2891
|
+
sendGhostSignal();
|
|
2892
|
+
}, intervalMs);
|
|
2893
|
+
}, intervalMs);
|
|
2894
|
+
}
|
|
2895
|
+
stopGhostSignalCollection() {
|
|
2896
|
+
if (this.ghostInterval) {
|
|
2897
|
+
clearInterval(this.ghostInterval);
|
|
2898
|
+
this.ghostInterval = null;
|
|
2899
|
+
this.ghostStartTime = null;
|
|
2900
|
+
}
|
|
2901
|
+
}
|
|
2902
|
+
async sendGhostSignals(durationMs) {
|
|
2903
|
+
if (!this.isInitialized || !this.config) return;
|
|
2904
|
+
const deviceInfo = this.deviceCollector.collect();
|
|
2905
|
+
const behavioralData = this.behavioralCollector.getData();
|
|
2906
|
+
const fingerprintData = await this.fingerprintManager.collect();
|
|
2907
|
+
const fingerprintjsData = {
|
|
2908
|
+
visitorId: fingerprintData.visitorId,
|
|
2909
|
+
confidence: fingerprintData.confidence,
|
|
2910
|
+
components: fingerprintData.components
|
|
2911
|
+
};
|
|
2912
|
+
const privacySignals = this.privacySignalCollector.collect();
|
|
2913
|
+
const browserCapabilities = this.browserCapabilityCollector.collect();
|
|
2914
|
+
const hardwareSignals = this.hardwareSignalCollector.collect();
|
|
2915
|
+
const formInteractions = this.formInteractionCollector.getData();
|
|
2916
|
+
const mouseSignals = this.behavioralCollector.getMouseSignals();
|
|
2917
|
+
const keyboardSignals = this.behavioralCollector.getKeyboardSignals();
|
|
2918
|
+
const pageInteractions = this.pageInteractionCollector.getData();
|
|
2919
|
+
const networkSignals = {
|
|
2920
|
+
connectionType: hardwareSignals.connectionType || void 0,
|
|
2921
|
+
effectiveType: hardwareSignals.effectiveType || void 0,
|
|
2922
|
+
downlink: hardwareSignals.downlink || void 0,
|
|
2923
|
+
rtt: hardwareSignals.rtt || void 0,
|
|
2924
|
+
saveData: hardwareSignals.saveData || void 0
|
|
2925
|
+
};
|
|
2926
|
+
const sessionInfo = {
|
|
2927
|
+
sessionId: this.sessionId || void 0,
|
|
2928
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2929
|
+
};
|
|
2930
|
+
const request = {
|
|
2931
|
+
userId: this.config.userId,
|
|
2932
|
+
device: deviceInfo,
|
|
2933
|
+
session: sessionInfo,
|
|
2934
|
+
behavioral: behavioralData,
|
|
2935
|
+
duration_ms: durationMs,
|
|
2936
|
+
fingerprintjs: fingerprintjsData || void 0,
|
|
2937
|
+
privacySignals,
|
|
2938
|
+
browserCapabilities,
|
|
2939
|
+
hardwareSignals,
|
|
2940
|
+
formInteractions,
|
|
2941
|
+
mouseSignals,
|
|
2942
|
+
keyboardSignals,
|
|
2943
|
+
pageInteractions,
|
|
2944
|
+
networkSignals,
|
|
2945
|
+
useCase: "ghost"
|
|
2946
|
+
};
|
|
2947
|
+
const url = `${DEFAULT_ENDPOINT}/fingerprint/ghost`;
|
|
2948
|
+
const headers = {
|
|
2949
|
+
"Content-Type": "application/json",
|
|
2950
|
+
"X-SDK-Source": "javascript"
|
|
2951
|
+
};
|
|
2952
|
+
const apiKey = this.config.apiKey;
|
|
2953
|
+
if (apiKey) {
|
|
2954
|
+
headers["x-keverd-key"] = apiKey;
|
|
2955
|
+
headers["X-API-KEY"] = apiKey;
|
|
2956
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
2852
2957
|
}
|
|
2958
|
+
await fetch(url, {
|
|
2959
|
+
method: "POST",
|
|
2960
|
+
headers,
|
|
2961
|
+
body: JSON.stringify(request)
|
|
2962
|
+
}).catch(() => {
|
|
2963
|
+
});
|
|
2853
2964
|
}
|
|
2854
2965
|
/**
|
|
2855
2966
|
* Get visitor data (fingerprint and risk assessment)
|
|
@@ -3035,8 +3146,7 @@ var KeverdSDK = class {
|
|
|
3035
3146
|
if (options.changeType) {
|
|
3036
3147
|
request.changeType = options.changeType;
|
|
3037
3148
|
}
|
|
3038
|
-
const
|
|
3039
|
-
const url = `${endpoint}/fingerprint/verify/${useCase}`;
|
|
3149
|
+
const url = `${DEFAULT_ENDPOINT}/fingerprint/verify/${useCase}`;
|
|
3040
3150
|
const headers = {
|
|
3041
3151
|
"Content-Type": "application/json",
|
|
3042
3152
|
"X-SDK-Source": "javascript"
|
|
@@ -3066,8 +3176,7 @@ var KeverdSDK = class {
|
|
|
3066
3176
|
if (!this.config) {
|
|
3067
3177
|
throw new Error("SDK not initialized");
|
|
3068
3178
|
}
|
|
3069
|
-
const
|
|
3070
|
-
const url = `${endpoint}/fingerprint/score`;
|
|
3179
|
+
const url = `${DEFAULT_ENDPOINT}/fingerprint/score`;
|
|
3071
3180
|
const headers = {
|
|
3072
3181
|
"Content-Type": "application/json",
|
|
3073
3182
|
"X-SDK-Source": "javascript"
|
|
@@ -3097,15 +3206,215 @@ var KeverdSDK = class {
|
|
|
3097
3206
|
generateSessionId() {
|
|
3098
3207
|
return `${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
3099
3208
|
}
|
|
3209
|
+
/**
|
|
3210
|
+
* Detect browser name from user agent
|
|
3211
|
+
*/
|
|
3212
|
+
_detectBrowser() {
|
|
3213
|
+
const ua = navigator.userAgent;
|
|
3214
|
+
if (ua.includes("Chrome")) return "Chrome";
|
|
3215
|
+
if (ua.includes("Firefox")) return "Firefox";
|
|
3216
|
+
if (ua.includes("Safari") && !ua.includes("Chrome")) return "Safari";
|
|
3217
|
+
if (ua.includes("Edge")) return "Edge";
|
|
3218
|
+
if (ua.includes("Opera")) return "Opera";
|
|
3219
|
+
return void 0;
|
|
3220
|
+
}
|
|
3221
|
+
/**
|
|
3222
|
+
* Detect OS from user agent
|
|
3223
|
+
*/
|
|
3224
|
+
_detectOS() {
|
|
3225
|
+
const ua = navigator.userAgent;
|
|
3226
|
+
if (ua.includes("Windows")) return "Windows";
|
|
3227
|
+
if (ua.includes("Mac OS")) return "macOS";
|
|
3228
|
+
if (ua.includes("Linux")) return "Linux";
|
|
3229
|
+
if (ua.includes("Android")) return "Android";
|
|
3230
|
+
if (ua.includes("iOS") || ua.includes("iPhone") || ua.includes("iPad")) return "iOS";
|
|
3231
|
+
return void 0;
|
|
3232
|
+
}
|
|
3233
|
+
/**
|
|
3234
|
+
* Start a new session (called automatically on init, but can be called manually)
|
|
3235
|
+
*/
|
|
3236
|
+
async startSession(userId, deviceHash, metadata) {
|
|
3237
|
+
if (!this.isInitialized || !this.config) {
|
|
3238
|
+
throw new Error("Keverd SDK not initialized. Call init() first.");
|
|
3239
|
+
}
|
|
3240
|
+
if (!this.sessionId) {
|
|
3241
|
+
this.sessionId = this.generateSessionId();
|
|
3242
|
+
}
|
|
3243
|
+
try {
|
|
3244
|
+
const url = `${DEFAULT_ENDPOINT}/dashboard/sessions/start`;
|
|
3245
|
+
const headers = {
|
|
3246
|
+
"Content-Type": "application/json"
|
|
3247
|
+
};
|
|
3248
|
+
const apiKey = this.config.apiKey;
|
|
3249
|
+
if (apiKey) {
|
|
3250
|
+
headers["x-keverd-key"] = apiKey;
|
|
3251
|
+
headers["X-API-KEY"] = apiKey;
|
|
3252
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
3253
|
+
}
|
|
3254
|
+
const deviceInfo = this.deviceCollector.collect();
|
|
3255
|
+
await fetch(url, {
|
|
3256
|
+
method: "POST",
|
|
3257
|
+
headers,
|
|
3258
|
+
body: JSON.stringify({
|
|
3259
|
+
session_id: this.sessionId,
|
|
3260
|
+
user_id: userId || this.config.userId,
|
|
3261
|
+
device_hash: deviceHash || deviceInfo.fingerprint,
|
|
3262
|
+
metadata: metadata || {},
|
|
3263
|
+
user_agent: navigator.userAgent,
|
|
3264
|
+
browser: this._detectBrowser(),
|
|
3265
|
+
os: this._detectOS(),
|
|
3266
|
+
platform: "web",
|
|
3267
|
+
sdk_type: "web",
|
|
3268
|
+
sdk_source: "javascript"
|
|
3269
|
+
})
|
|
3270
|
+
});
|
|
3271
|
+
if (this.config.debug) {
|
|
3272
|
+
console.log(`[Keverd SDK] Session started: ${this.sessionId}`);
|
|
3273
|
+
}
|
|
3274
|
+
} catch (error) {
|
|
3275
|
+
if (this.config.debug) {
|
|
3276
|
+
console.warn("[Keverd SDK] Failed to start session on server:", error);
|
|
3277
|
+
}
|
|
3278
|
+
}
|
|
3279
|
+
}
|
|
3280
|
+
/**
|
|
3281
|
+
* End the current session
|
|
3282
|
+
*/
|
|
3283
|
+
async endSession() {
|
|
3284
|
+
if (!this.isInitialized || !this.config || !this.sessionId) {
|
|
3285
|
+
return;
|
|
3286
|
+
}
|
|
3287
|
+
try {
|
|
3288
|
+
const url = `${DEFAULT_ENDPOINT}/dashboard/sessions/${this.sessionId}/end`;
|
|
3289
|
+
const headers = {
|
|
3290
|
+
"Content-Type": "application/json"
|
|
3291
|
+
};
|
|
3292
|
+
const apiKey = this.config.apiKey;
|
|
3293
|
+
if (apiKey) {
|
|
3294
|
+
headers["x-keverd-key"] = apiKey;
|
|
3295
|
+
headers["X-API-KEY"] = apiKey;
|
|
3296
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
3297
|
+
}
|
|
3298
|
+
await fetch(url, {
|
|
3299
|
+
method: "POST",
|
|
3300
|
+
headers
|
|
3301
|
+
});
|
|
3302
|
+
if (this.config.debug) {
|
|
3303
|
+
console.log(`[Keverd SDK] Session ended: ${this.sessionId}`);
|
|
3304
|
+
}
|
|
3305
|
+
} catch (error) {
|
|
3306
|
+
if (this.config.debug) {
|
|
3307
|
+
console.warn("[Keverd SDK] Failed to end session on server:", error);
|
|
3308
|
+
}
|
|
3309
|
+
}
|
|
3310
|
+
}
|
|
3311
|
+
/**
|
|
3312
|
+
* Pause the current session (e.g., when app goes to background)
|
|
3313
|
+
*/
|
|
3314
|
+
async pauseSession() {
|
|
3315
|
+
if (!this.isInitialized || !this.config || !this.sessionId) {
|
|
3316
|
+
return;
|
|
3317
|
+
}
|
|
3318
|
+
try {
|
|
3319
|
+
const url = `${DEFAULT_ENDPOINT}/dashboard/sessions/${this.sessionId}/pause`;
|
|
3320
|
+
const headers = {
|
|
3321
|
+
"Content-Type": "application/json"
|
|
3322
|
+
};
|
|
3323
|
+
const apiKey = this.config.apiKey;
|
|
3324
|
+
if (apiKey) {
|
|
3325
|
+
headers["x-keverd-key"] = apiKey;
|
|
3326
|
+
headers["X-API-KEY"] = apiKey;
|
|
3327
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
3328
|
+
}
|
|
3329
|
+
await fetch(url, {
|
|
3330
|
+
method: "POST",
|
|
3331
|
+
headers
|
|
3332
|
+
});
|
|
3333
|
+
if (this.config.debug) {
|
|
3334
|
+
console.log(`[Keverd SDK] Session paused: ${this.sessionId}`);
|
|
3335
|
+
}
|
|
3336
|
+
} catch (error) {
|
|
3337
|
+
if (this.config.debug) {
|
|
3338
|
+
console.warn("[Keverd SDK] Failed to pause session on server:", error);
|
|
3339
|
+
}
|
|
3340
|
+
}
|
|
3341
|
+
}
|
|
3342
|
+
/**
|
|
3343
|
+
* Resume a paused session (e.g., when app comes to foreground)
|
|
3344
|
+
*/
|
|
3345
|
+
async resumeSession() {
|
|
3346
|
+
if (!this.isInitialized || !this.config || !this.sessionId) {
|
|
3347
|
+
return;
|
|
3348
|
+
}
|
|
3349
|
+
try {
|
|
3350
|
+
const url = `${DEFAULT_ENDPOINT}/dashboard/sessions/${this.sessionId}/resume`;
|
|
3351
|
+
const headers = {
|
|
3352
|
+
"Content-Type": "application/json"
|
|
3353
|
+
};
|
|
3354
|
+
const apiKey = this.config.apiKey;
|
|
3355
|
+
if (apiKey) {
|
|
3356
|
+
headers["x-keverd-key"] = apiKey;
|
|
3357
|
+
headers["X-API-KEY"] = apiKey;
|
|
3358
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
3359
|
+
}
|
|
3360
|
+
await fetch(url, {
|
|
3361
|
+
method: "POST",
|
|
3362
|
+
headers
|
|
3363
|
+
});
|
|
3364
|
+
if (this.config.debug) {
|
|
3365
|
+
console.log(`[Keverd SDK] Session resumed: ${this.sessionId}`);
|
|
3366
|
+
}
|
|
3367
|
+
} catch (error) {
|
|
3368
|
+
if (this.config.debug) {
|
|
3369
|
+
console.warn("[Keverd SDK] Failed to resume session on server:", error);
|
|
3370
|
+
}
|
|
3371
|
+
}
|
|
3372
|
+
}
|
|
3373
|
+
/**
|
|
3374
|
+
* Get current session status
|
|
3375
|
+
*/
|
|
3376
|
+
async getSessionStatus() {
|
|
3377
|
+
if (!this.isInitialized || !this.config || !this.sessionId) {
|
|
3378
|
+
return null;
|
|
3379
|
+
}
|
|
3380
|
+
try {
|
|
3381
|
+
const url = `${DEFAULT_ENDPOINT}/dashboard/sessions/${this.sessionId}/status`;
|
|
3382
|
+
const headers = {};
|
|
3383
|
+
const apiKey = this.config.apiKey;
|
|
3384
|
+
if (apiKey) {
|
|
3385
|
+
headers["x-keverd-key"] = apiKey;
|
|
3386
|
+
headers["X-API-KEY"] = apiKey;
|
|
3387
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
3388
|
+
}
|
|
3389
|
+
const response = await fetch(url, {
|
|
3390
|
+
method: "GET",
|
|
3391
|
+
headers
|
|
3392
|
+
});
|
|
3393
|
+
if (!response.ok) {
|
|
3394
|
+
return null;
|
|
3395
|
+
}
|
|
3396
|
+
return await response.json();
|
|
3397
|
+
} catch (error) {
|
|
3398
|
+
if (this.config.debug) {
|
|
3399
|
+
console.warn("[Keverd SDK] Failed to get session status:", error);
|
|
3400
|
+
}
|
|
3401
|
+
return null;
|
|
3402
|
+
}
|
|
3403
|
+
}
|
|
3100
3404
|
/**
|
|
3101
3405
|
* Destroy the SDK instance
|
|
3102
3406
|
*/
|
|
3103
|
-
destroy() {
|
|
3407
|
+
async destroy() {
|
|
3408
|
+
if (this.sessionId) {
|
|
3409
|
+
await this.endSession();
|
|
3410
|
+
}
|
|
3104
3411
|
this.behavioralCollector.stop();
|
|
3105
3412
|
this.formInteractionCollector.stop();
|
|
3106
3413
|
this.pageInteractionCollector.stop();
|
|
3107
3414
|
this.fingerprintManager.clearCache();
|
|
3108
3415
|
this.isInitialized = false;
|
|
3416
|
+
this.stopGhostSignalCollection();
|
|
3417
|
+
this.ghostSignalCount = 0;
|
|
3109
3418
|
if (this.config?.debug) {
|
|
3110
3419
|
console.log("[Keverd SDK] Destroyed");
|
|
3111
3420
|
}
|
|
@@ -3145,22 +3454,20 @@ exports.KeverdService = class KeverdService {
|
|
|
3145
3454
|
throw new Error("Keverd SDK: apiKey is required");
|
|
3146
3455
|
}
|
|
3147
3456
|
this.config = {
|
|
3148
|
-
endpoint: config.endpoint || this.getDefaultEndpoint(),
|
|
3149
3457
|
debug: false,
|
|
3150
3458
|
...config
|
|
3151
3459
|
};
|
|
3152
3460
|
Keverd.init({
|
|
3153
3461
|
apiKey: this.config.apiKey,
|
|
3154
|
-
endpoint: this.config.endpoint,
|
|
3155
3462
|
userId: this.config.userId,
|
|
3156
3463
|
debug: this.config.debug || false
|
|
3157
3464
|
});
|
|
3158
3465
|
this.isInitialized = true;
|
|
3159
3466
|
if (this.config.debug) {
|
|
3160
|
-
console.log("[Keverd SDK] Initialized successfully"
|
|
3161
|
-
endpoint: this.config.endpoint
|
|
3162
|
-
});
|
|
3467
|
+
console.log("[Keverd SDK] Initialized successfully");
|
|
3163
3468
|
}
|
|
3469
|
+
Keverd.startSession().catch(() => {
|
|
3470
|
+
});
|
|
3164
3471
|
}
|
|
3165
3472
|
/**
|
|
3166
3473
|
* Get visitor data (fingerprint and risk assessment)
|
|
@@ -3225,22 +3532,115 @@ exports.KeverdService = class KeverdService {
|
|
|
3225
3532
|
recommendedAction: response.recommended_action
|
|
3226
3533
|
};
|
|
3227
3534
|
}
|
|
3228
|
-
/**
|
|
3229
|
-
* Get default endpoint
|
|
3230
|
-
*/
|
|
3231
|
-
getDefaultEndpoint() {
|
|
3232
|
-
return "https://api.keverd.com";
|
|
3233
|
-
}
|
|
3234
3535
|
/**
|
|
3235
3536
|
* Generate a session ID
|
|
3236
3537
|
*/
|
|
3237
3538
|
generateSessionId() {
|
|
3238
3539
|
return `${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
3239
3540
|
}
|
|
3541
|
+
/**
|
|
3542
|
+
* Start a new session (called automatically on init, but can be called manually)
|
|
3543
|
+
*/
|
|
3544
|
+
startSession(userId, deviceHash, metadata) {
|
|
3545
|
+
if (!this.isInitialized || !this.config) {
|
|
3546
|
+
return rxjs.throwError(() => ({
|
|
3547
|
+
message: "Keverd SDK not initialized. Call init() first.",
|
|
3548
|
+
code: "SDK_NOT_INITIALIZED"
|
|
3549
|
+
}));
|
|
3550
|
+
}
|
|
3551
|
+
return rxjs.from(Keverd.startSession(userId, deviceHash, metadata)).pipe(
|
|
3552
|
+
operators.catchError((error) => {
|
|
3553
|
+
if (this.config?.debug) {
|
|
3554
|
+
console.warn("[Keverd SDK] Failed to start session:", error);
|
|
3555
|
+
}
|
|
3556
|
+
return rxjs.throwError(() => error);
|
|
3557
|
+
})
|
|
3558
|
+
);
|
|
3559
|
+
}
|
|
3560
|
+
/**
|
|
3561
|
+
* End the current session
|
|
3562
|
+
*/
|
|
3563
|
+
endSession() {
|
|
3564
|
+
if (!this.isInitialized || !this.config) {
|
|
3565
|
+
return rxjs.throwError(() => ({
|
|
3566
|
+
message: "Keverd SDK not initialized. Call init() first.",
|
|
3567
|
+
code: "SDK_NOT_INITIALIZED"
|
|
3568
|
+
}));
|
|
3569
|
+
}
|
|
3570
|
+
return rxjs.from(Keverd.endSession()).pipe(
|
|
3571
|
+
operators.catchError((error) => {
|
|
3572
|
+
if (this.config?.debug) {
|
|
3573
|
+
console.warn("[Keverd SDK] Failed to end session:", error);
|
|
3574
|
+
}
|
|
3575
|
+
return rxjs.throwError(() => error);
|
|
3576
|
+
})
|
|
3577
|
+
);
|
|
3578
|
+
}
|
|
3579
|
+
/**
|
|
3580
|
+
* Pause the current session (e.g., when app goes to background)
|
|
3581
|
+
*/
|
|
3582
|
+
pauseSession() {
|
|
3583
|
+
if (!this.isInitialized || !this.config) {
|
|
3584
|
+
return rxjs.throwError(() => ({
|
|
3585
|
+
message: "Keverd SDK not initialized. Call init() first.",
|
|
3586
|
+
code: "SDK_NOT_INITIALIZED"
|
|
3587
|
+
}));
|
|
3588
|
+
}
|
|
3589
|
+
return rxjs.from(Keverd.pauseSession()).pipe(
|
|
3590
|
+
operators.catchError((error) => {
|
|
3591
|
+
if (this.config?.debug) {
|
|
3592
|
+
console.warn("[Keverd SDK] Failed to pause session:", error);
|
|
3593
|
+
}
|
|
3594
|
+
return rxjs.throwError(() => error);
|
|
3595
|
+
})
|
|
3596
|
+
);
|
|
3597
|
+
}
|
|
3598
|
+
/**
|
|
3599
|
+
* Resume a paused session (e.g., when app comes to foreground)
|
|
3600
|
+
*/
|
|
3601
|
+
resumeSession() {
|
|
3602
|
+
if (!this.isInitialized || !this.config) {
|
|
3603
|
+
return rxjs.throwError(() => ({
|
|
3604
|
+
message: "Keverd SDK not initialized. Call init() first.",
|
|
3605
|
+
code: "SDK_NOT_INITIALIZED"
|
|
3606
|
+
}));
|
|
3607
|
+
}
|
|
3608
|
+
return rxjs.from(Keverd.resumeSession()).pipe(
|
|
3609
|
+
operators.catchError((error) => {
|
|
3610
|
+
if (this.config?.debug) {
|
|
3611
|
+
console.warn("[Keverd SDK] Failed to resume session:", error);
|
|
3612
|
+
}
|
|
3613
|
+
return rxjs.throwError(() => error);
|
|
3614
|
+
})
|
|
3615
|
+
);
|
|
3616
|
+
}
|
|
3617
|
+
/**
|
|
3618
|
+
* Get current session status
|
|
3619
|
+
*/
|
|
3620
|
+
getSessionStatus() {
|
|
3621
|
+
if (!this.isInitialized || !this.config) {
|
|
3622
|
+
return rxjs.throwError(() => ({
|
|
3623
|
+
message: "Keverd SDK not initialized. Call init() first.",
|
|
3624
|
+
code: "SDK_NOT_INITIALIZED"
|
|
3625
|
+
}));
|
|
3626
|
+
}
|
|
3627
|
+
return rxjs.from(Keverd.getSessionStatus()).pipe(
|
|
3628
|
+
operators.catchError((error) => {
|
|
3629
|
+
if (this.config?.debug) {
|
|
3630
|
+
console.warn("[Keverd SDK] Failed to get session status:", error);
|
|
3631
|
+
}
|
|
3632
|
+
return rxjs.throwError(() => error);
|
|
3633
|
+
})
|
|
3634
|
+
);
|
|
3635
|
+
}
|
|
3240
3636
|
/**
|
|
3241
3637
|
* Destroy the SDK instance
|
|
3242
3638
|
*/
|
|
3243
3639
|
destroy() {
|
|
3640
|
+
if (this.isInitialized) {
|
|
3641
|
+
Keverd.endSession().catch(() => {
|
|
3642
|
+
});
|
|
3643
|
+
}
|
|
3244
3644
|
Keverd.destroy();
|
|
3245
3645
|
this.isInitialized = false;
|
|
3246
3646
|
this.config = null;
|
|
@@ -3276,7 +3676,6 @@ exports.KeverdModule = class KeverdModule {
|
|
|
3276
3676
|
* imports: [
|
|
3277
3677
|
* KeverdModule.forRoot({
|
|
3278
3678
|
* apiKey: 'your-api-key',
|
|
3279
|
-
* endpoint: 'https://api.keverd.com'
|
|
3280
3679
|
* })
|
|
3281
3680
|
* ]
|
|
3282
3681
|
* })
|