unshared-clientjs-sdk 1.0.3 → 1.0.5

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/client.d.ts CHANGED
@@ -2,13 +2,49 @@ export interface UnsharedLabsClientConfig {
2
2
  apiKey: string;
3
3
  clientId: string;
4
4
  baseUrl?: string;
5
+ emailServiceUrl?: string;
6
+ }
7
+ export interface ProcessUserEventData {
8
+ id: string;
9
+ event_type: string;
10
+ user_id: string;
11
+ email_address: string;
12
+ ip_address: string;
13
+ device_id: string;
14
+ session_hash: string;
15
+ user_agent: string;
16
+ client_timestamp: string;
17
+ }
18
+ export interface ProcessUserEventEvent {
19
+ data: ProcessUserEventData[];
20
+ status: string;
21
+ statusDetails: string;
22
+ }
23
+ export interface ProcessUserEventAnalysis {
24
+ status: string;
25
+ isUserFlagged: boolean;
26
+ statusDetails: string;
27
+ }
28
+ export interface ProcessUserEventResponseData {
29
+ event: ProcessUserEventEvent;
30
+ analysis: ProcessUserEventAnalysis;
31
+ }
32
+ export interface ProcessUserEventResponse {
33
+ success: boolean;
34
+ data: ProcessUserEventResponseData;
5
35
  }
6
36
  export default class UnsharedLabsClient {
7
- private _UNSHAREDLABS_DEFAULT_URL;
8
- private _UNSHAREDLABS_INTERNAL_CLIENT;
9
37
  private _apiKey;
10
38
  private _clientId;
39
+ private _apiBaseUrl;
40
+ private _emailServiceUrl;
11
41
  constructor(config: UnsharedLabsClientConfig);
12
- private _getSupabaseClient;
42
+ private _getBasicAuthHeader;
43
+ /**
44
+ * @deprecated This method is deprecated and will be removed in a future version. Use `processUserEvent` instead.
45
+ */
13
46
  submitEvent(eventType: string, userId: string, ipAddress: string, deviceId: string, sessionHash: string, userAgent: string, clientTimestamp: string, eventDetails?: Map<string, any> | null): Promise<any>;
47
+ processUserEvent(eventType: string, userId: string, ipAddress: string, deviceId: string, sessionHash: string, userAgent: string, emailAddress: string, eventDetails?: Map<string, any> | null): Promise<ProcessUserEventResponse>;
48
+ triggerEmailVerification(userId: string, emailAddress?: string): Promise<any>;
49
+ verify(userId: string, code: string): Promise<any>;
14
50
  }
package/dist/client.js CHANGED
@@ -1,52 +1 @@
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 = atob('aHR0cHM6Ly95c3Vmem5jZXR0d2VyYnlhbXlneC5zdXBhYmFzZS5jbwo=');
8
- let url = config.baseUrl || this._UNSHAREDLABS_DEFAULT_URL;
9
- this._apiKey = config.apiKey;
10
- this._clientId = atob(config.clientId);
11
- this._UNSHAREDLABS_INTERNAL_CLIENT = this._getSupabaseClient(url, this._apiKey);
12
- }
13
- _getSupabaseClient(url, apiKey) {
14
- try {
15
- return (0, supabase_js_1.createClient)(url, apiKey, { auth: { persistSession: false } });
16
- }
17
- catch (error) {
18
- throw new Error(`Failed to create client; please reach out to unshared labs support`);
19
- }
20
- }
21
- async submitEvent(eventType, userId, ipAddress, deviceId, sessionHash, userAgent, clientTimestamp, eventDetails) {
22
- try {
23
- const encryptedUserId = (0, util_1.encryptData)(userId, this._apiKey);
24
- const encryptedIpAddress = (0, util_1.encryptData)(ipAddress, this._apiKey);
25
- const encryptedDeviceId = (0, util_1.encryptData)(deviceId, this._apiKey);
26
- const encryptedSessionHash = (0, util_1.encryptData)(sessionHash, this._apiKey);
27
- const encryptedUserAgent = (0, util_1.encryptData)(userAgent, this._apiKey);
28
- const encryptedEventDetails = (0, util_1.encryptData)(eventDetails ? JSON.stringify([...eventDetails.entries()]) : null, this._apiKey);
29
- const body = {
30
- user_id: encryptedUserId,
31
- event_type: eventType,
32
- ip_address: encryptedIpAddress,
33
- device_id: encryptedDeviceId,
34
- session_hash: encryptedSessionHash,
35
- user_agent: encryptedUserAgent,
36
- client_timestamp: clientTimestamp,
37
- event_details: encryptedEventDetails,
38
- };
39
- const { data, error } = await this._UNSHAREDLABS_INTERNAL_CLIENT
40
- .from(this._clientId)
41
- .insert(body);
42
- if (error) {
43
- throw error;
44
- }
45
- return data;
46
- }
47
- catch (error) {
48
- throw new Error(`Failed to call UnsharedLabs API: ${error instanceof Error ? error.message : JSON.stringify(error)}`);
49
- }
50
- }
51
- }
52
- exports.default = UnsharedLabsClient;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});const util_1=require("./util");class UnsharedLabsClient{constructor(t){this._apiBaseUrl="https://api.unsharedlabs.com",this._emailServiceUrl="https://emailservice.unsharedlabs.com",this._apiKey=t.apiKey,this._clientId=atob(t.clientId),t.baseUrl&&(this._apiBaseUrl=t.baseUrl),t.emailServiceUrl&&(this._emailServiceUrl=t.emailServiceUrl)}_getBasicAuthHeader(){const t=`${this._clientId}:${this._apiKey}`;return`Basic ${Buffer.from(t).toString("base64")}`}async submitEvent(t,e,i,r,a,s,n,o){try{const c=(0,util_1.encryptData)(e,this._apiKey),h=(0,util_1.encryptData)(i,this._apiKey),l=(0,util_1.encryptData)(r,this._apiKey),d=(0,util_1.encryptData)(a,this._apiKey),y=(0,util_1.encryptData)(s,this._apiKey),p={user_id:c,event_type:t,ip_address:h,device_id:l,session_hash:d,user_agent:y,client_timestamp:n,event_details:(0,util_1.encryptData)(o?JSON.stringify([...o.entries()]):null,this._apiKey)},u=await fetch(`${this._apiBaseUrl}/api/v1/submitEvent`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:this._getBasicAuthHeader()},body:JSON.stringify(p)});if(!u.ok){const t=await u.json().catch(()=>({error:u.statusText}));throw new Error(`API returned error: ${JSON.stringify(t)}`)}const _=await u.json();return{status:u.status,statusText:u.statusText,data:_}}catch(t){throw new Error(`Failed to call UnsharedLabs API: ${t instanceof Error?t.message:JSON.stringify(t)}`)}}async processUserEvent(t,e,i,r,a,s,n,o){try{const c=(0,util_1.encryptData)(e,this._apiKey),h=(0,util_1.encryptData)(i,this._apiKey),l=(0,util_1.encryptData)(r,this._apiKey),d=(0,util_1.encryptData)(a,this._apiKey),y=(0,util_1.encryptData)(s,this._apiKey),p=(0,util_1.encryptData)(n,this._apiKey),u={user_id:c,event_type:t,ip_address:h,device_id:l,session_hash:d,user_agent:y,email_address:p,event_details:(0,util_1.encryptData)(o?JSON.stringify([...o.entries()]):null,this._apiKey)},_=await fetch(`${this._apiBaseUrl}/api/v1/processUserEvent`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:this._getBasicAuthHeader()},body:JSON.stringify(u)});if(!_.ok){const t=await _.json().catch(()=>({error:_.statusText}));throw new Error(`API returned error: ${JSON.stringify(t)}`)}return await _.json()}catch(t){throw new Error(`Failed to process user event: ${t instanceof Error?t.message:JSON.stringify(t)}`)}}async triggerEmailVerification(t,e){try{const i=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;let r;if(i.test(t))r=t;else{if(!e||!i.test(e))throw new Error("Invalid email address: userId must be an email address or emailAddress must be provided");r=e}const a=await fetch(`${this._emailServiceUrl}/api/send-email`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:this._getBasicAuthHeader()},body:JSON.stringify({to:r})});if(!a.ok){const t=await a.json().catch(()=>({error:a.statusText}));throw new Error(`Email service returned error: ${JSON.stringify(t)}`)}return await a.json()}catch(t){throw new Error(`Failed to trigger email verification: ${t instanceof Error?t.message:JSON.stringify(t)}`)}}async verify(t,e){try{const i=await fetch(`${this._emailServiceUrl}/api/verify`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:this._getBasicAuthHeader()},body:JSON.stringify({user_id:t,code:e})});if(!i.ok){const t=await i.json().catch(()=>({error:i.statusText}));throw new Error(`Verification service returned error: ${JSON.stringify(t)}`)}return await i.json()}catch(t){throw new Error(`Failed to verify code: ${t instanceof Error?t.message:JSON.stringify(t)}`)}}}exports.default=UnsharedLabsClient;
package/dist/util.js CHANGED
@@ -1,34 +1 @@
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
- }
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.encryptData=encryptData,exports.decryptData=decryptData;const crypto_1=require("crypto");function encryptData(t,e){if(null==t)return"unknown";const r="string"==typeof t?t:JSON.stringify(t),a=(0,crypto_1.createHash)("sha256").update(e).digest(),n=(0,crypto_1.randomBytes)(16),c=(0,crypto_1.createCipheriv)("aes-256-cbc",a,n);let o=c.update(r,"utf8","base64");return o+=c.final("base64"),n.toString("base64")+":"+o}function decryptData(t,e){if("unknown"===t)return null;const r=t.split(":");if(2!==r.length)throw new Error("Invalid encrypted data format");const[a,n]=r,c=Buffer.from(a,"base64"),o=(0,crypto_1.createHash)("sha256").update(e).digest(),s=(0,crypto_1.createDecipheriv)("aes-256-cbc",o,c);let p=s.update(n,"base64","utf8");return p+=s.final("utf8"),p}
package/package.json CHANGED
@@ -1,15 +1,17 @@
1
1
  {
2
2
  "name": "unshared-clientjs-sdk",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "",
5
5
  "main": "dist/client.js",
6
6
  "types": "dist/client.d.ts",
7
7
  "scripts": {
8
- "build": "tsc",
8
+ "build": "node scripts/build.js",
9
+ "build:tsc": "tsc",
9
10
  "test": "vitest run",
10
11
  "dev": "vitest --watch",
11
12
  "prepublishOnly": "npm run build && npm test",
12
- "test-server": "ts-node test-server/server.ts"
13
+ "test-server": "ts-node test-server/server.ts",
14
+ "test-email-service": "ts-node test-email-service/server.ts"
13
15
  },
14
16
  "files": [
15
17
  "dist",
@@ -22,11 +24,9 @@
22
24
  "@types/express": "^4.17.21",
23
25
  "@types/node": "^24.10.1",
24
26
  "express": "^4.18.2",
27
+ "terser": "^5.44.1",
25
28
  "ts-node": "^10.9.2",
26
29
  "typescript": "^5.9.3",
27
30
  "vitest": "^4.0.14"
28
- },
29
- "dependencies": {
30
- "@supabase/supabase-js": "^2.86.0"
31
31
  }
32
32
  }