@ik-firewall/core 2.4.1 → 2.4.3

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.cjs CHANGED
@@ -185,13 +185,22 @@ var IKHmac = class {
185
185
  constructor(secret) {
186
186
  this.secret = secret;
187
187
  }
188
+ sortObject(obj) {
189
+ if (obj === null || typeof obj !== "object") return obj;
190
+ if (Array.isArray(obj)) return obj.map((i) => this.sortObject(i));
191
+ const sorted = {};
192
+ Object.keys(obj).sort().forEach((key) => {
193
+ sorted[key] = this.sortObject(obj[key]);
194
+ });
195
+ return sorted;
196
+ }
188
197
  /**
189
198
  * Verifies that a response from the IK-Firewall server is authentic.
190
199
  */
191
200
  async verify(data) {
192
201
  if (!data || !data.signature) return false;
193
202
  const { signature, ...rest } = data;
194
- const payload = JSON.stringify(rest);
203
+ const payload = JSON.stringify(this.sortObject(rest));
195
204
  try {
196
205
  const crypto = typeof window === "undefined" ? (await import(
197
206
  /* webpackIgnore: true */
@@ -281,12 +290,13 @@ var ConfigManager = class {
281
290
  const response = await fetch(`${endpoint}?licenseKey=${instanceConfig?.licenseKey || ""}&instanceId=${instanceId}&version=2.3.0`);
282
291
  if (response.ok) {
283
292
  const data = await response.json();
284
- if (this.config.hmacSecret) {
285
- const verifier = new IKHmac(this.config.hmacSecret);
286
- if (!verifier.verify(data)) {
287
- console.error("[IK_SYNC] \u{1F6A8} Signature verification failed! Remote config rejected.");
288
- return;
289
- }
293
+ const defaultSecret = "default-secret-change-in-production";
294
+ const hmacSecret = this.config.hmacSecret;
295
+ const verificationKey = hmacSecret && hmacSecret !== defaultSecret ? hmacSecret : defaultSecret;
296
+ const verifier = new IKHmac(verificationKey);
297
+ if (!await verifier.verify(data)) {
298
+ console.error("[IK_SYNC] \u{1F6A8} Signature verification failed! Remote config rejected.");
299
+ return;
290
300
  }
291
301
  await this.setInstanceConfig(instanceId, {
292
302
  billingStatus: data.billingStatus,
@@ -372,12 +382,13 @@ var ConfigManager = class {
372
382
  });
373
383
  if (response.ok) {
374
384
  const data = await response.json();
375
- if (this.config.hmacSecret) {
376
- const verifier = new IKHmac(this.config.hmacSecret);
377
- if (!verifier.verify(data)) {
378
- console.error("[IK_REGISTRY] \u{1F6A8} Registration signature mismatch. Data rejected!");
379
- return false;
380
- }
385
+ const defaultSecret = "default-secret-change-in-production";
386
+ const hmacSecret = this.config.hmacSecret;
387
+ const verificationKey = hmacSecret && hmacSecret !== defaultSecret ? hmacSecret : defaultSecret;
388
+ const verifier = new IKHmac(verificationKey);
389
+ if (!await verifier.verify(data)) {
390
+ console.error("[IK_REGISTRY] \u{1F6A8} Registration signature mismatch. Data rejected!");
391
+ return false;
381
392
  }
382
393
  await this.setInstanceConfig(instanceId, {
383
394
  licenseKey: data.licenseKey,
@@ -1561,12 +1572,13 @@ var UsageTracker = class {
1561
1572
  await this.sendBatch(payload);
1562
1573
  } catch (error) {
1563
1574
  console.error("[IK_TRACKER] Batch send failed:", error.message);
1564
- const isAuthError = error.message?.includes("401");
1565
- if (!isAuthError) {
1575
+ const isAuthError = error.message?.includes("401") || error.message?.includes("403");
1576
+ if (isAuthError) {
1577
+ console.warn("[IK_TRACKER] \u{1F512} Unauthorized/Forbidden: Subscription invalid or blocked. Discarding batch.");
1578
+ this.config.setBlockedStatus(instanceId, true);
1579
+ } else {
1566
1580
  console.log("[IK_TRACKER] Queuing for retry...");
1567
1581
  this.handleFailure(payload);
1568
- } else {
1569
- console.warn("[IK_TRACKER] Unauthorized: Please check your IK_FIREWALL_SECRET and License Key. Discarding batch.");
1570
1582
  }
1571
1583
  } finally {
1572
1584
  this.flushInProgress = false;
@@ -1579,15 +1591,16 @@ var UsageTracker = class {
1579
1591
  if (process.env.IK_FIREWALL_DISABLED === "true" || process.env.NEXT_PUBLIC_IK_FIREWALL_DISABLED === "true") {
1580
1592
  return;
1581
1593
  }
1582
- if (hmacSecret) {
1583
- try {
1584
- const crypto = typeof window === "undefined" ? (await import("crypto")).default : null;
1585
- if (crypto && crypto.createHmac) {
1586
- const { signature: _sig, ...signablePayload } = payload;
1587
- payload.signature = crypto.createHmac("sha256", hmacSecret).update(JSON.stringify(signablePayload)).digest("hex");
1588
- }
1589
- } catch (e) {
1594
+ const defaultSecret = "default-secret-change-in-production";
1595
+ const signingKey = hmacSecret && hmacSecret !== defaultSecret ? hmacSecret : payload.licenseKey || defaultSecret;
1596
+ try {
1597
+ const crypto = typeof window === "undefined" ? (await import("crypto")).default : null;
1598
+ if (crypto && crypto.createHmac) {
1599
+ const { signature: _sig, ...signablePayload } = payload;
1600
+ const sortedPayload = this.sortObject(signablePayload);
1601
+ payload.signature = crypto.createHmac("sha256", signingKey).update(JSON.stringify(sortedPayload)).digest("hex");
1590
1602
  }
1603
+ } catch (e) {
1591
1604
  }
1592
1605
  const response = await fetch(endpoint, {
1593
1606
  method: "POST",
@@ -1626,6 +1639,15 @@ var UsageTracker = class {
1626
1639
  await this.hooks.persistState(`ik_retry_${payload.timestamp}`, JSON.stringify(payload));
1627
1640
  }
1628
1641
  }
1642
+ sortObject(obj) {
1643
+ if (obj === null || typeof obj !== "object") return obj;
1644
+ if (Array.isArray(obj)) return obj.map((i) => this.sortObject(i));
1645
+ const sorted = {};
1646
+ Object.keys(obj).sort().forEach((key) => {
1647
+ sorted[key] = this.sortObject(obj[key]);
1648
+ });
1649
+ return sorted;
1650
+ }
1629
1651
  getBuffer() {
1630
1652
  return Array.from(this.aggregationMap.values());
1631
1653
  }
@@ -1882,6 +1904,7 @@ var IKFirewallCore = class _IKFirewallCore {
1882
1904
  if (mode === "anthropic") return "claude-3-5-sonnet-20241022";
1883
1905
  if (mode === "deepseek") return "deepseek-reasoner";
1884
1906
  if (mode === "gemini") return "gemini-1.5-pro";
1907
+ if (mode === "perplexity") return role === "high_performance" ? "sonar-pro" : "sonar";
1885
1908
  return role === "high_performance" ? "gpt-4o" : "gpt-4o-mini";
1886
1909
  }
1887
1910
  /**
package/dist/index.js CHANGED
@@ -143,13 +143,22 @@ var IKHmac = class {
143
143
  constructor(secret) {
144
144
  this.secret = secret;
145
145
  }
146
+ sortObject(obj) {
147
+ if (obj === null || typeof obj !== "object") return obj;
148
+ if (Array.isArray(obj)) return obj.map((i) => this.sortObject(i));
149
+ const sorted = {};
150
+ Object.keys(obj).sort().forEach((key) => {
151
+ sorted[key] = this.sortObject(obj[key]);
152
+ });
153
+ return sorted;
154
+ }
146
155
  /**
147
156
  * Verifies that a response from the IK-Firewall server is authentic.
148
157
  */
149
158
  async verify(data) {
150
159
  if (!data || !data.signature) return false;
151
160
  const { signature, ...rest } = data;
152
- const payload = JSON.stringify(rest);
161
+ const payload = JSON.stringify(this.sortObject(rest));
153
162
  try {
154
163
  const crypto = typeof window === "undefined" ? (await import(
155
164
  /* webpackIgnore: true */
@@ -239,12 +248,13 @@ var ConfigManager = class {
239
248
  const response = await fetch(`${endpoint}?licenseKey=${instanceConfig?.licenseKey || ""}&instanceId=${instanceId}&version=2.3.0`);
240
249
  if (response.ok) {
241
250
  const data = await response.json();
242
- if (this.config.hmacSecret) {
243
- const verifier = new IKHmac(this.config.hmacSecret);
244
- if (!verifier.verify(data)) {
245
- console.error("[IK_SYNC] \u{1F6A8} Signature verification failed! Remote config rejected.");
246
- return;
247
- }
251
+ const defaultSecret = "default-secret-change-in-production";
252
+ const hmacSecret = this.config.hmacSecret;
253
+ const verificationKey = hmacSecret && hmacSecret !== defaultSecret ? hmacSecret : defaultSecret;
254
+ const verifier = new IKHmac(verificationKey);
255
+ if (!await verifier.verify(data)) {
256
+ console.error("[IK_SYNC] \u{1F6A8} Signature verification failed! Remote config rejected.");
257
+ return;
248
258
  }
249
259
  await this.setInstanceConfig(instanceId, {
250
260
  billingStatus: data.billingStatus,
@@ -330,12 +340,13 @@ var ConfigManager = class {
330
340
  });
331
341
  if (response.ok) {
332
342
  const data = await response.json();
333
- if (this.config.hmacSecret) {
334
- const verifier = new IKHmac(this.config.hmacSecret);
335
- if (!verifier.verify(data)) {
336
- console.error("[IK_REGISTRY] \u{1F6A8} Registration signature mismatch. Data rejected!");
337
- return false;
338
- }
343
+ const defaultSecret = "default-secret-change-in-production";
344
+ const hmacSecret = this.config.hmacSecret;
345
+ const verificationKey = hmacSecret && hmacSecret !== defaultSecret ? hmacSecret : defaultSecret;
346
+ const verifier = new IKHmac(verificationKey);
347
+ if (!await verifier.verify(data)) {
348
+ console.error("[IK_REGISTRY] \u{1F6A8} Registration signature mismatch. Data rejected!");
349
+ return false;
339
350
  }
340
351
  await this.setInstanceConfig(instanceId, {
341
352
  licenseKey: data.licenseKey,
@@ -1519,12 +1530,13 @@ var UsageTracker = class {
1519
1530
  await this.sendBatch(payload);
1520
1531
  } catch (error) {
1521
1532
  console.error("[IK_TRACKER] Batch send failed:", error.message);
1522
- const isAuthError = error.message?.includes("401");
1523
- if (!isAuthError) {
1533
+ const isAuthError = error.message?.includes("401") || error.message?.includes("403");
1534
+ if (isAuthError) {
1535
+ console.warn("[IK_TRACKER] \u{1F512} Unauthorized/Forbidden: Subscription invalid or blocked. Discarding batch.");
1536
+ this.config.setBlockedStatus(instanceId, true);
1537
+ } else {
1524
1538
  console.log("[IK_TRACKER] Queuing for retry...");
1525
1539
  this.handleFailure(payload);
1526
- } else {
1527
- console.warn("[IK_TRACKER] Unauthorized: Please check your IK_FIREWALL_SECRET and License Key. Discarding batch.");
1528
1540
  }
1529
1541
  } finally {
1530
1542
  this.flushInProgress = false;
@@ -1537,15 +1549,16 @@ var UsageTracker = class {
1537
1549
  if (process.env.IK_FIREWALL_DISABLED === "true" || process.env.NEXT_PUBLIC_IK_FIREWALL_DISABLED === "true") {
1538
1550
  return;
1539
1551
  }
1540
- if (hmacSecret) {
1541
- try {
1542
- const crypto = typeof window === "undefined" ? (await import("crypto")).default : null;
1543
- if (crypto && crypto.createHmac) {
1544
- const { signature: _sig, ...signablePayload } = payload;
1545
- payload.signature = crypto.createHmac("sha256", hmacSecret).update(JSON.stringify(signablePayload)).digest("hex");
1546
- }
1547
- } catch (e) {
1552
+ const defaultSecret = "default-secret-change-in-production";
1553
+ const signingKey = hmacSecret && hmacSecret !== defaultSecret ? hmacSecret : payload.licenseKey || defaultSecret;
1554
+ try {
1555
+ const crypto = typeof window === "undefined" ? (await import("crypto")).default : null;
1556
+ if (crypto && crypto.createHmac) {
1557
+ const { signature: _sig, ...signablePayload } = payload;
1558
+ const sortedPayload = this.sortObject(signablePayload);
1559
+ payload.signature = crypto.createHmac("sha256", signingKey).update(JSON.stringify(sortedPayload)).digest("hex");
1548
1560
  }
1561
+ } catch (e) {
1549
1562
  }
1550
1563
  const response = await fetch(endpoint, {
1551
1564
  method: "POST",
@@ -1584,6 +1597,15 @@ var UsageTracker = class {
1584
1597
  await this.hooks.persistState(`ik_retry_${payload.timestamp}`, JSON.stringify(payload));
1585
1598
  }
1586
1599
  }
1600
+ sortObject(obj) {
1601
+ if (obj === null || typeof obj !== "object") return obj;
1602
+ if (Array.isArray(obj)) return obj.map((i) => this.sortObject(i));
1603
+ const sorted = {};
1604
+ Object.keys(obj).sort().forEach((key) => {
1605
+ sorted[key] = this.sortObject(obj[key]);
1606
+ });
1607
+ return sorted;
1608
+ }
1587
1609
  getBuffer() {
1588
1610
  return Array.from(this.aggregationMap.values());
1589
1611
  }
@@ -1840,6 +1862,7 @@ var IKFirewallCore = class _IKFirewallCore {
1840
1862
  if (mode === "anthropic") return "claude-3-5-sonnet-20241022";
1841
1863
  if (mode === "deepseek") return "deepseek-reasoner";
1842
1864
  if (mode === "gemini") return "gemini-1.5-pro";
1865
+ if (mode === "perplexity") return role === "high_performance" ? "sonar-pro" : "sonar";
1843
1866
  return role === "high_performance" ? "gpt-4o" : "gpt-4o-mini";
1844
1867
  }
1845
1868
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ik-firewall/core",
3
- "version": "2.4.1",
3
+ "version": "2.4.3",
4
4
  "type": "module",
5
5
  "description": "The core IK Firewall engine for semantic-driven AI optimization.",
6
6
  "main": "./dist/index.js",