unshared-clientjs-sdk 1.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.
@@ -0,0 +1,12 @@
1
+ export interface UnsharedLabsClientConfig {
2
+ apiKey: string;
3
+ baseUrl?: string;
4
+ }
5
+ export default class UnsharedLabsClient {
6
+ private _UNSHAREDLABS_DEFAULT_URL;
7
+ private _UNSHAREDLABS_INTERNAL_CLIENT;
8
+ private _apiKey;
9
+ constructor(config: UnsharedLabsClientConfig);
10
+ private _getSupabaseClient;
11
+ submitEvent(eventType: string, userId: string, ipAddress: string, deviceId: string, sessionHash: string, userAgent: string, clientTimestamp: string, eventDetails?: Map<string, any> | null): Promise<any>;
12
+ }
package/dist/client.js ADDED
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const supabase_js_1 = require("@supabase/supabase-js");
4
+ const util_1 = require("./util");
5
+ class UnsharedLabsClient {
6
+ constructor(config) {
7
+ this._UNSHAREDLABS_DEFAULT_URL = 'https://ysufzncettwerbyamygx.supabase.co';
8
+ let url = config.baseUrl || this._UNSHAREDLABS_DEFAULT_URL;
9
+ this._apiKey = config.apiKey;
10
+ this._UNSHAREDLABS_INTERNAL_CLIENT = this._getSupabaseClient(url, this._apiKey);
11
+ }
12
+ _getSupabaseClient(url, apiKey) {
13
+ try {
14
+ return (0, supabase_js_1.createClient)(url, apiKey, { auth: { persistSession: false } });
15
+ }
16
+ catch (error) {
17
+ throw new Error(`Failed to create client; please reach out to unshared labs support`);
18
+ }
19
+ }
20
+ async submitEvent(eventType, userId, ipAddress, deviceId, sessionHash, userAgent, clientTimestamp, eventDetails) {
21
+ try {
22
+ const encryptedUserId = (0, util_1.encryptData)(userId, this._apiKey);
23
+ const encryptedIpAddress = (0, util_1.encryptData)(ipAddress, this._apiKey);
24
+ const encryptedDeviceId = (0, util_1.encryptData)(deviceId, this._apiKey);
25
+ const encryptedSessionHash = (0, util_1.encryptData)(sessionHash, this._apiKey);
26
+ const encryptedUserAgent = (0, util_1.encryptData)(userAgent, this._apiKey);
27
+ const encryptedEventDetails = (0, util_1.encryptData)(eventDetails ? JSON.stringify([...eventDetails.entries()]) : null, this._apiKey);
28
+ const body = {
29
+ user_id: encryptedUserId,
30
+ event_type: eventType,
31
+ ip_address: encryptedIpAddress,
32
+ device_id: encryptedDeviceId,
33
+ session_hash: encryptedSessionHash,
34
+ user_agent: encryptedUserAgent,
35
+ client_timestamp: clientTimestamp,
36
+ event_details: encryptedEventDetails,
37
+ };
38
+ const { data, error } = await this._UNSHAREDLABS_INTERNAL_CLIENT
39
+ .from('session_heartbeats')
40
+ .insert(body);
41
+ if (error) {
42
+ throw error;
43
+ }
44
+ return data;
45
+ }
46
+ catch (error) {
47
+ throw new Error(`Failed to call UnsharedLabs API: ${error instanceof Error ? error.message : JSON.stringify(error)}`);
48
+ }
49
+ }
50
+ }
51
+ exports.default = UnsharedLabsClient;
package/dist/util.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare function encryptData(data: string | null | undefined, clientCredentials: string): string;
2
+ export declare function decryptData(encryptedData: string, clientCredentials: string): string | null;
package/dist/util.js ADDED
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.encryptData = encryptData;
4
+ exports.decryptData = decryptData;
5
+ const crypto_1 = require("crypto");
6
+ function encryptData(data, clientCredentials) {
7
+ if (data === null || data === undefined) {
8
+ return 'unknown';
9
+ }
10
+ const dataString = typeof data === 'string' ? data : JSON.stringify(data);
11
+ // Derive a 32-byte key from client credentials using SHA-256
12
+ const key = (0, crypto_1.createHash)('sha256').update(clientCredentials).digest();
13
+ const iv = (0, crypto_1.randomBytes)(16);
14
+ const cipher = (0, crypto_1.createCipheriv)('aes-256-cbc', key, iv);
15
+ let encrypted = cipher.update(dataString, 'utf8', 'base64');
16
+ encrypted += cipher.final('base64');
17
+ return iv.toString('base64') + ':' + encrypted;
18
+ }
19
+ function decryptData(encryptedData, clientCredentials) {
20
+ if (encryptedData === 'unknown') {
21
+ return null;
22
+ }
23
+ const parts = encryptedData.split(':');
24
+ if (parts.length !== 2) {
25
+ throw new Error('Invalid encrypted data format');
26
+ }
27
+ const [ivBase64, encrypted] = parts;
28
+ const iv = Buffer.from(ivBase64, 'base64');
29
+ const key = (0, crypto_1.createHash)('sha256').update(clientCredentials).digest();
30
+ const decipher = (0, crypto_1.createDecipheriv)('aes-256-cbc', key, iv);
31
+ let decrypted = decipher.update(encrypted, 'base64', 'utf8');
32
+ decrypted += decipher.final('utf8');
33
+ return decrypted;
34
+ }
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "unshared-clientjs-sdk",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "dist/client.js",
6
+ "types": "dist/client.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "test": "vitest run",
10
+ "dev": "vitest --watch",
11
+ "prepublishOnly": "npm run build && npm test",
12
+ "test-server": "ts-node test-server/server.ts"
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "keywords": [],
18
+ "author": "",
19
+ "license": "MIT",
20
+ "devDependencies": {
21
+ "@types/express": "^4.17.21",
22
+ "@types/node": "^24.10.1",
23
+ "express": "^4.18.2",
24
+ "ts-node": "^10.9.2",
25
+ "typescript": "^5.9.3",
26
+ "vitest": "^4.0.14"
27
+ },
28
+ "dependencies": {
29
+ "@supabase/supabase-js": "^2.86.0"
30
+ }
31
+ }