@cloudsignal/pwa-sdk 1.2.4 → 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.
@@ -52,10 +52,10 @@ async function generateHMACSignature(secret, organizationId, timestamp, method,
52
52
  const signature = await crypto.subtle.sign("HMAC", key, encoder.encode(canonicalString));
53
53
  return toBase64(signature);
54
54
  }
55
- async function generateAuthHeaders(organizationId, organizationSecret, method, url, body) {
55
+ async function generateAuthHeaders(organizationId, organizationPublishableKey, method, url, body) {
56
56
  const timestamp = Math.floor(Date.now() / 1e3).toString();
57
57
  const signature = await generateHMACSignature(
58
- organizationSecret,
58
+ organizationPublishableKey,
59
59
  organizationId,
60
60
  timestamp,
61
61
  method,
@@ -69,11 +69,11 @@ async function generateAuthHeaders(organizationId, organizationSecret, method, u
69
69
  "Content-Type": "application/json"
70
70
  };
71
71
  }
72
- async function makeAuthenticatedRequest(organizationId, organizationSecret, method, url, body) {
72
+ async function makeAuthenticatedRequest(organizationId, organizationPublishableKey, method, url, body) {
73
73
  const bodyStr = body ? JSON.stringify(body) : void 0;
74
74
  const headers = await generateAuthHeaders(
75
75
  organizationId,
76
- organizationSecret,
76
+ organizationPublishableKey,
77
77
  method,
78
78
  url,
79
79
  bodyStr
@@ -93,5 +93,5 @@ function isValidUUID(value) {
93
93
  }
94
94
 
95
95
  export { generateAuthHeaders, generateHMACSignature, isValidUUID, makeAuthenticatedRequest };
96
- //# sourceMappingURL=chunk-IMM7VF4N.js.map
97
- //# sourceMappingURL=chunk-IMM7VF4N.js.map
96
+ //# sourceMappingURL=chunk-IQHSODT4.js.map
97
+ //# sourceMappingURL=chunk-IQHSODT4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/hmac.ts"],"names":[],"mappings":"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","file":"chunk-IQHSODT4.js","sourcesContent":["/**\n * HMAC Authentication Utilities\n * Implements CloudSignal's HMAC signature scheme for API authentication\n */\n\n/**\n * Convert ArrayBuffer to hex string\n */\nfunction toHex(buffer: ArrayBuffer): string {\n return Array.from(new Uint8Array(buffer))\n .map(b => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\n/**\n * Convert ArrayBuffer to base64 string\n */\nfunction toBase64(buffer: ArrayBuffer): string {\n return btoa(String.fromCharCode(...new Uint8Array(buffer)))\n}\n\n/**\n * Generate HMAC signature for CloudSignal API requests\n *\n * @param secret - Signing key (organization publishable key, pk_*)\n * @param organizationId - Organization UUID\n * @param timestamp - Unix timestamp string\n * @param method - HTTP method (GET, POST, etc.)\n * @param url - Full URL or path\n * @param body - Request body (optional)\n * @returns Base64-encoded HMAC signature\n */\nexport async function generateHMACSignature(\n secret: string,\n organizationId: string,\n timestamp: string,\n method: string,\n url: string,\n body: string = ''\n): Promise<string> {\n const encoder = new TextEncoder()\n\n // Parse URL to extract path and query\n let path: string\n let query: string\n\n try {\n const urlObj = url.startsWith('http')\n ? new URL(url)\n : new URL(url, 'https://pwa.cloudsignal.app')\n path = urlObj.pathname\n query = urlObj.search ? urlObj.search.slice(1) : ''\n } catch {\n // Fallback for simple paths\n const queryIndex = url.indexOf('?')\n if (queryIndex > -1) {\n path = url.slice(0, queryIndex)\n query = url.slice(queryIndex + 1)\n } else {\n path = url\n query = ''\n }\n }\n\n // Build canonical string parts\n const canonicalParts = [\n method.toUpperCase(),\n path,\n query,\n organizationId,\n timestamp,\n ]\n\n // Add body hash if body is present\n if (body && body.length > 0) {\n const bodyHashBuffer = await crypto.subtle.digest('SHA-256', encoder.encode(body))\n const bodyHashHex = toHex(bodyHashBuffer)\n canonicalParts.push(bodyHashHex)\n }\n\n // Join parts with newlines\n const canonicalString = canonicalParts.join('\\n')\n\n // Import secret as HMAC key\n const key = await crypto.subtle.importKey(\n 'raw',\n encoder.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign']\n )\n\n // Sign the canonical string\n const signature = await crypto.subtle.sign('HMAC', key, encoder.encode(canonicalString))\n\n return toBase64(signature)\n}\n\n/**\n * Generate authentication headers for CloudSignal API requests\n *\n * @param organizationId - Organization UUID\n * @param organizationPublishableKey - Organization publishable key (pk_*)\n * @param method - HTTP method\n * @param url - Request URL\n * @param body - Request body (optional)\n * @returns Headers object with authentication headers\n */\nexport async function generateAuthHeaders(\n organizationId: string,\n organizationPublishableKey: string,\n method: string,\n url: string,\n body?: string\n): Promise<Record<string, string>> {\n const timestamp = Math.floor(Date.now() / 1000).toString()\n\n const signature = await generateHMACSignature(\n organizationPublishableKey,\n organizationId,\n timestamp,\n method,\n url,\n body || ''\n )\n\n return {\n 'X-CloudSignal-Organization-ID': organizationId,\n 'X-CloudSignal-Timestamp': timestamp,\n 'X-CloudSignal-Signature': signature,\n 'Content-Type': 'application/json',\n }\n}\n\n/**\n * Make an authenticated request to CloudSignal API\n *\n * @param organizationId - Organization UUID\n * @param organizationPublishableKey - Organization publishable key (pk_*)\n * @param method - HTTP method\n * @param url - Request URL\n * @param body - Request body (optional)\n * @returns Fetch Response\n */\nexport async function makeAuthenticatedRequest(\n organizationId: string,\n organizationPublishableKey: string,\n method: string,\n url: string,\n body?: Record<string, any>\n): Promise<Response> {\n const bodyStr = body ? JSON.stringify(body) : undefined\n\n const headers = await generateAuthHeaders(\n organizationId,\n organizationPublishableKey,\n method,\n url,\n bodyStr\n )\n\n const options: RequestInit = {\n method,\n headers,\n }\n\n if (bodyStr) {\n options.body = bodyStr\n }\n\n return fetch(url, options)\n}\n\n/**\n * Validate UUID format\n * \n * @param value - String to validate\n * @returns Whether the string is a valid UUID\n */\nexport function isValidUUID(value: string | null | undefined): boolean {\n if (!value || typeof value !== 'string') return false\n return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value)\n}\n"]}
@@ -0,0 +1,3 @@
1
+ export { generateAuthHeaders, generateHMACSignature, isValidUUID, makeAuthenticatedRequest } from './chunk-IQHSODT4.js';
2
+ //# sourceMappingURL=hmac-WITZIX2O.js.map
3
+ //# sourceMappingURL=hmac-WITZIX2O.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"hmac-LWLR6F7Z.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"hmac-WITZIX2O.js"}
package/dist/index.cjs CHANGED
@@ -72,10 +72,10 @@ async function generateHMACSignature(secret, organizationId, timestamp, method,
72
72
  const signature = await crypto.subtle.sign("HMAC", key, encoder.encode(canonicalString));
73
73
  return toBase64(signature);
74
74
  }
75
- async function generateAuthHeaders(organizationId, organizationSecret, method, url, body) {
75
+ async function generateAuthHeaders(organizationId, organizationPublishableKey, method, url, body) {
76
76
  const timestamp = Math.floor(Date.now() / 1e3).toString();
77
77
  const signature = await generateHMACSignature(
78
- organizationSecret,
78
+ organizationPublishableKey,
79
79
  organizationId,
80
80
  timestamp,
81
81
  method,
@@ -89,11 +89,11 @@ async function generateAuthHeaders(organizationId, organizationSecret, method, u
89
89
  "Content-Type": "application/json"
90
90
  };
91
91
  }
92
- async function makeAuthenticatedRequest(organizationId, organizationSecret, method, url, body) {
92
+ async function makeAuthenticatedRequest(organizationId, organizationPublishableKey, method, url, body) {
93
93
  const bodyStr = body ? JSON.stringify(body) : void 0;
94
94
  const headers = await generateAuthHeaders(
95
95
  organizationId,
96
- organizationSecret,
96
+ organizationPublishableKey,
97
97
  method,
98
98
  url,
99
99
  bodyStr
@@ -1046,13 +1046,13 @@ function createAuthContext(config) {
1046
1046
  onTokenExpired: config.onTokenExpired
1047
1047
  };
1048
1048
  }
1049
- if (!config.organizationSecret) {
1050
- throw new Error("Either userToken or organizationSecret is required");
1049
+ if (!config.organizationPublishableKey) {
1050
+ throw new Error("Either userToken or organizationPublishableKey is required");
1051
1051
  }
1052
1052
  return {
1053
1053
  mode: "hmac",
1054
1054
  organizationId: config.organizationId,
1055
- organizationSecret: config.organizationSecret
1055
+ organizationPublishableKey: config.organizationPublishableKey
1056
1056
  };
1057
1057
  }
1058
1058
  async function makeAuthenticatedRequestWithContext(authContext, method, url, body, onTokenExpired) {
@@ -1073,12 +1073,12 @@ async function makeAuthenticatedRequestWithContext(authContext, method, url, bod
1073
1073
  );
1074
1074
  }
1075
1075
  const { makeAuthenticatedRequest: makeAuthenticatedRequest4 } = await Promise.resolve().then(() => (init_hmac(), hmac_exports));
1076
- if (!authContext.organizationSecret) {
1077
- throw new Error("organizationSecret required for HMAC auth mode");
1076
+ if (!authContext.organizationPublishableKey) {
1077
+ throw new Error("organizationPublishableKey required for HMAC auth mode");
1078
1078
  }
1079
1079
  return makeAuthenticatedRequest4(
1080
1080
  authContext.organizationId,
1081
- authContext.organizationSecret,
1081
+ authContext.organizationPublishableKey,
1082
1082
  method,
1083
1083
  url,
1084
1084
  body
@@ -1141,15 +1141,6 @@ function removeRegistrationId(organizationId, serviceId) {
1141
1141
  const key = `registration_${organizationId}_${serviceId}`;
1142
1142
  return removeStorageItem(key);
1143
1143
  }
1144
- function isInstallationRegistered(organizationId, serviceId) {
1145
- const key = `install_registered_${organizationId}_${serviceId}`;
1146
- return getStorageItem(key) === true;
1147
- }
1148
- function markInstallationRegistered(organizationId, serviceId, registrationId) {
1149
- const key = `install_registered_${organizationId}_${serviceId}`;
1150
- setStorageItem(`install_id_${organizationId}_${serviceId}`, registrationId);
1151
- return setStorageItem(key, true);
1152
- }
1153
1144
  var IndexedDBStorage = class {
1154
1145
  constructor(dbName = "CloudSignalPWA", dbVersion = 1) {
1155
1146
  this.db = null;
@@ -1356,7 +1347,7 @@ var PushNotificationManager = class {
1356
1347
  this.deviceDetector = new DeviceDetector();
1357
1348
  this.authContext = createAuthContext({
1358
1349
  organizationId: options.organizationId,
1359
- organizationSecret: options.organizationSecret,
1350
+ organizationPublishableKey: options.organizationPublishableKey,
1360
1351
  userToken: options.userToken
1361
1352
  });
1362
1353
  this.onRegistered = options.onRegistered;
@@ -1595,72 +1586,6 @@ var PushNotificationManager = class {
1595
1586
  return null;
1596
1587
  }
1597
1588
  }
1598
- /**
1599
- * Register PWA installation without push subscription.
1600
- * This tracks users who installed the PWA but haven't subscribed to notifications.
1601
- * Called automatically when installation is detected.
1602
- *
1603
- * @returns Installation registration result or null if already registered/failed
1604
- */
1605
- async registerInstallation() {
1606
- try {
1607
- if (isInstallationRegistered(this.organizationId, this.serviceId)) {
1608
- this.log("Installation already registered, skipping");
1609
- return null;
1610
- }
1611
- const fingerprint = await generateBrowserFingerprint();
1612
- const deviceInfo = this.deviceDetector.getDeviceInfo();
1613
- const platformInfo = this.deviceDetector.getPlatformInfo();
1614
- const installationData = {
1615
- service_id: this.serviceId,
1616
- browser_fingerprint: fingerprint || void 0,
1617
- device_type: deviceInfo.deviceType,
1618
- device_model: deviceInfo.deviceModel,
1619
- browser_name: platformInfo.browser,
1620
- browser_version: platformInfo.browserVersion,
1621
- os_name: platformInfo.os,
1622
- os_version: platformInfo.osVersion,
1623
- user_agent: platformInfo.userAgent,
1624
- display_mode: "standalone",
1625
- is_installed: true,
1626
- timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
1627
- language: navigator.language || "en-US"
1628
- };
1629
- const url = `${this.serviceUrl}/api/v1/registration/install-only`;
1630
- const response = await makeAuthenticatedRequestWithContext(
1631
- this.authContext,
1632
- "POST",
1633
- url,
1634
- installationData,
1635
- this.onTokenExpired
1636
- );
1637
- if (!response.ok) {
1638
- const errorText = await response.text();
1639
- throw new Error(`Installation registration failed: ${response.status} - ${errorText}`);
1640
- }
1641
- const result = await response.json();
1642
- markInstallationRegistered(this.organizationId, this.serviceId, result.registration_id);
1643
- this.log(`Installation registered successfully: ${result.registration_id}`);
1644
- return { registrationId: result.registration_id };
1645
- } catch (error) {
1646
- const err = error instanceof Error ? error : new Error(String(error));
1647
- this.log(`Installation registration failed: ${err.message}`, "error");
1648
- this.onError?.(err);
1649
- return null;
1650
- }
1651
- }
1652
- /**
1653
- * Check if installation is already registered
1654
- */
1655
- isInstallationRegistered() {
1656
- return isInstallationRegistered(this.organizationId, this.serviceId);
1657
- }
1658
- /**
1659
- * Get stored installation registration ID
1660
- */
1661
- getInstallationId() {
1662
- return getStorageItem(`install_id_${this.organizationId}_${this.serviceId}`);
1663
- }
1664
1589
  /**
1665
1590
  * Request notification permission
1666
1591
  */
@@ -1755,7 +1680,7 @@ var HeartbeatManager = class {
1755
1680
  this.onTokenExpired = options.onTokenExpired;
1756
1681
  this.authContext = createAuthContext({
1757
1682
  organizationId: options.organizationId,
1758
- organizationSecret: options.organizationSecret,
1683
+ organizationPublishableKey: options.organizationPublishableKey,
1759
1684
  userToken: options.userToken
1760
1685
  });
1761
1686
  this.config = {
@@ -3192,7 +3117,7 @@ var IOSInstallBanner = class {
3192
3117
 
3193
3118
  // src/CloudSignalPWA.ts
3194
3119
  var DEFAULT_SERVICE_URL = "https://pwa.cloudsignal.app";
3195
- var SDK_VERSION = "1.2.3";
3120
+ var SDK_VERSION = "1.2.0";
3196
3121
  var CloudSignalPWA = class {
3197
3122
  constructor(config) {
3198
3123
  this.initialized = false;
@@ -3206,12 +3131,12 @@ var CloudSignalPWA = class {
3206
3131
  this.config = config;
3207
3132
  this.serviceUrl = config.serviceUrl || DEFAULT_SERVICE_URL;
3208
3133
  this.debug = config.debug ?? false;
3209
- if (!config.organizationSecret && !config.userToken) {
3210
- throw new Error("Either organizationSecret or userToken must be provided");
3134
+ if (!config.organizationPublishableKey && !config.userToken) {
3135
+ throw new Error("Either organizationPublishableKey or userToken must be provided");
3211
3136
  }
3212
3137
  this.authContext = createAuthContext({
3213
3138
  organizationId: config.organizationId,
3214
- organizationSecret: config.organizationSecret,
3139
+ organizationPublishableKey: config.organizationPublishableKey,
3215
3140
  userToken: config.userToken
3216
3141
  });
3217
3142
  this.deviceDetector = new DeviceDetector();
@@ -3232,7 +3157,7 @@ var CloudSignalPWA = class {
3232
3157
  this.pushNotificationManager = new PushNotificationManager({
3233
3158
  serviceUrl: this.serviceUrl,
3234
3159
  organizationId: config.organizationId,
3235
- organizationSecret: config.organizationSecret,
3160
+ organizationPublishableKey: config.organizationPublishableKey,
3236
3161
  userToken: config.userToken,
3237
3162
  onTokenExpired: config.onTokenExpired,
3238
3163
  serviceId: config.serviceId,
@@ -3251,7 +3176,7 @@ var CloudSignalPWA = class {
3251
3176
  this.heartbeatManager = new HeartbeatManager({
3252
3177
  serviceUrl: this.serviceUrl,
3253
3178
  organizationId: config.organizationId,
3254
- organizationSecret: config.organizationSecret,
3179
+ organizationPublishableKey: config.organizationPublishableKey,
3255
3180
  userToken: config.userToken,
3256
3181
  onTokenExpired: config.onTokenExpired,
3257
3182
  config: config.heartbeat,
@@ -3333,20 +3258,11 @@ var CloudSignalPWA = class {
3333
3258
  this.configureNotificationAnalytics(swReg);
3334
3259
  }
3335
3260
  if (this.iosInstallBanner && this.config.iosInstallBanner?.showOnFirstVisit !== false) {
3336
- const installState2 = this.installationManager.getState();
3337
- if (!installState2.isInstalled) {
3261
+ const installState = this.installationManager.getState();
3262
+ if (!installState.isInstalled) {
3338
3263
  this.iosInstallBanner.show();
3339
3264
  }
3340
3265
  }
3341
- const installState = this.installationManager.getState();
3342
- if (installState.isInstalled) {
3343
- this.log("PWA installation detected, registering...");
3344
- const installResult = await this.pushNotificationManager.registerInstallation();
3345
- if (installResult) {
3346
- this.log(`Installation registered: ${installResult.registrationId}`);
3347
- this.emit("install:registered", { registrationId: installResult.registrationId });
3348
- }
3349
- }
3350
3266
  this.initialized = true;
3351
3267
  const result = {
3352
3268
  success: true,