@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 +48 -25
- package/dist/index.js +48 -25
- package/package.json +1 -1
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
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
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
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
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 (
|
|
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
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
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
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
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
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
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 (
|
|
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
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
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
|
/**
|