@ik-firewall/core 2.3.6 → 2.4.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.
- package/dist/index.cjs +41 -10
- package/dist/index.js +41 -10
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -202,6 +202,7 @@ var ConfigManager = class {
|
|
|
202
202
|
config;
|
|
203
203
|
registry;
|
|
204
204
|
hooks;
|
|
205
|
+
blockedInstances = /* @__PURE__ */ new Set();
|
|
205
206
|
constructor(initialConfig, hooks) {
|
|
206
207
|
this.config = initialConfig;
|
|
207
208
|
this.hooks = hooks;
|
|
@@ -308,11 +309,27 @@ var ConfigManager = class {
|
|
|
308
309
|
if (instanceId && this.config.instanceConfigs?.[instanceId]) {
|
|
309
310
|
merged = { ...merged, ...this.config.instanceConfigs[instanceId] };
|
|
310
311
|
}
|
|
312
|
+
if (instanceId && this.blockedInstances.has(instanceId)) {
|
|
313
|
+
merged.billingStatus = "blocked";
|
|
314
|
+
}
|
|
311
315
|
if (override) {
|
|
312
316
|
merged = { ...merged, ...override };
|
|
313
317
|
}
|
|
314
318
|
return merged;
|
|
315
319
|
}
|
|
320
|
+
/**
|
|
321
|
+
* Updates the live blocked status for an instance (Kill-Switch).
|
|
322
|
+
* This is used by UsageTracker when it receives a response from the central server.
|
|
323
|
+
*/
|
|
324
|
+
setBlockedStatus(instanceId, blocked) {
|
|
325
|
+
if (blocked) {
|
|
326
|
+
this.blockedInstances.add(instanceId);
|
|
327
|
+
this.setInstanceConfig(instanceId, { billingStatus: "blocked" });
|
|
328
|
+
} else {
|
|
329
|
+
this.blockedInstances.delete(instanceId);
|
|
330
|
+
this.setInstanceConfig(instanceId, { billingStatus: "active" });
|
|
331
|
+
}
|
|
332
|
+
}
|
|
316
333
|
updateConfig(newConfig) {
|
|
317
334
|
this.config = {
|
|
318
335
|
...this.config,
|
|
@@ -1528,8 +1545,14 @@ var UsageTracker = class {
|
|
|
1528
1545
|
try {
|
|
1529
1546
|
await this.sendBatch(payload);
|
|
1530
1547
|
} catch (error) {
|
|
1531
|
-
console.error("[IK_TRACKER] Batch send failed
|
|
1532
|
-
|
|
1548
|
+
console.error("[IK_TRACKER] Batch send failed:", error.message);
|
|
1549
|
+
const isAuthError = error.message?.includes("401");
|
|
1550
|
+
if (!isAuthError) {
|
|
1551
|
+
console.log("[IK_TRACKER] Queuing for retry...");
|
|
1552
|
+
this.handleFailure(payload);
|
|
1553
|
+
} else {
|
|
1554
|
+
console.warn("[IK_TRACKER] Unauthorized: Please check your IK_FIREWALL_SECRET and License Key. Discarding batch.");
|
|
1555
|
+
}
|
|
1533
1556
|
} finally {
|
|
1534
1557
|
this.flushInProgress = false;
|
|
1535
1558
|
}
|
|
@@ -1538,6 +1561,9 @@ var UsageTracker = class {
|
|
|
1538
1561
|
const baseUrl = this.config.get("centralReportEndpoint") || "https://ik-firewall.vercel.app";
|
|
1539
1562
|
const endpoint = `${baseUrl.replace(/\/$/, "")}/api/v1/report`;
|
|
1540
1563
|
const hmacSecret = this.config.get("hmacSecret") || process.env.IK_FIREWALL_SECRET;
|
|
1564
|
+
if (process.env.IK_FIREWALL_DISABLED === "true" || process.env.NEXT_PUBLIC_IK_FIREWALL_DISABLED === "true") {
|
|
1565
|
+
return;
|
|
1566
|
+
}
|
|
1541
1567
|
if (hmacSecret) {
|
|
1542
1568
|
try {
|
|
1543
1569
|
const crypto = typeof window === "undefined" ? (await import("crypto")).default : null;
|
|
@@ -1558,6 +1584,16 @@ var UsageTracker = class {
|
|
|
1558
1584
|
if (!response.ok) {
|
|
1559
1585
|
throw new Error(`HTTP Error: ${response.status} ${response.statusText}`);
|
|
1560
1586
|
}
|
|
1587
|
+
try {
|
|
1588
|
+
const data = await response.json();
|
|
1589
|
+
if (data && (data.status === "blocked" || data.billingStatus === "blocked")) {
|
|
1590
|
+
this.config.setBlockedStatus(payload.instanceId, true);
|
|
1591
|
+
console.warn(`[IK_TRACKER] \u{1F6E1}\uFE0F Kill-Switch triggered for ${payload.instanceId}: Subscription inactive/blocked.`);
|
|
1592
|
+
} else if (data && (data.status === "active" || data.billingStatus === "active" || data.status === "trial")) {
|
|
1593
|
+
this.config.setBlockedStatus(payload.instanceId, false);
|
|
1594
|
+
}
|
|
1595
|
+
} catch (e) {
|
|
1596
|
+
}
|
|
1561
1597
|
this.hooks?.onFlushSuccess?.(payload);
|
|
1562
1598
|
}
|
|
1563
1599
|
async handleFailure(payload) {
|
|
@@ -1860,16 +1896,11 @@ var IKFirewallCore = class _IKFirewallCore {
|
|
|
1860
1896
|
}
|
|
1861
1897
|
if (instanceId) {
|
|
1862
1898
|
this.configManager.ensureInstanceConfig(instanceId);
|
|
1863
|
-
this.configManager.syncRemoteConfig(instanceId).catch((err) => {
|
|
1864
|
-
console.warn("[IK_CORE] Heartbeat sync failed:", err);
|
|
1865
|
-
});
|
|
1866
1899
|
}
|
|
1867
1900
|
const mergedConfig = this.configManager.getMergedConfig(instanceId);
|
|
1868
|
-
if (instanceId && mergedConfig?.
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
return this.getEmptyMetrics();
|
|
1872
|
-
}
|
|
1901
|
+
if (instanceId && mergedConfig?.billingStatus === "blocked") {
|
|
1902
|
+
this.hooks?.onStatus?.("\u26A0\uFE0F [IK_FIREWALL] Subscription inactive. Optimization bypassed (Fail-Safe mode).");
|
|
1903
|
+
return this.getEmptyMetrics();
|
|
1873
1904
|
}
|
|
1874
1905
|
let auditProvider = this.localProvider;
|
|
1875
1906
|
let overrideProvider = null;
|
package/dist/index.js
CHANGED
|
@@ -160,6 +160,7 @@ var ConfigManager = class {
|
|
|
160
160
|
config;
|
|
161
161
|
registry;
|
|
162
162
|
hooks;
|
|
163
|
+
blockedInstances = /* @__PURE__ */ new Set();
|
|
163
164
|
constructor(initialConfig, hooks) {
|
|
164
165
|
this.config = initialConfig;
|
|
165
166
|
this.hooks = hooks;
|
|
@@ -266,11 +267,27 @@ var ConfigManager = class {
|
|
|
266
267
|
if (instanceId && this.config.instanceConfigs?.[instanceId]) {
|
|
267
268
|
merged = { ...merged, ...this.config.instanceConfigs[instanceId] };
|
|
268
269
|
}
|
|
270
|
+
if (instanceId && this.blockedInstances.has(instanceId)) {
|
|
271
|
+
merged.billingStatus = "blocked";
|
|
272
|
+
}
|
|
269
273
|
if (override) {
|
|
270
274
|
merged = { ...merged, ...override };
|
|
271
275
|
}
|
|
272
276
|
return merged;
|
|
273
277
|
}
|
|
278
|
+
/**
|
|
279
|
+
* Updates the live blocked status for an instance (Kill-Switch).
|
|
280
|
+
* This is used by UsageTracker when it receives a response from the central server.
|
|
281
|
+
*/
|
|
282
|
+
setBlockedStatus(instanceId, blocked) {
|
|
283
|
+
if (blocked) {
|
|
284
|
+
this.blockedInstances.add(instanceId);
|
|
285
|
+
this.setInstanceConfig(instanceId, { billingStatus: "blocked" });
|
|
286
|
+
} else {
|
|
287
|
+
this.blockedInstances.delete(instanceId);
|
|
288
|
+
this.setInstanceConfig(instanceId, { billingStatus: "active" });
|
|
289
|
+
}
|
|
290
|
+
}
|
|
274
291
|
updateConfig(newConfig) {
|
|
275
292
|
this.config = {
|
|
276
293
|
...this.config,
|
|
@@ -1486,8 +1503,14 @@ var UsageTracker = class {
|
|
|
1486
1503
|
try {
|
|
1487
1504
|
await this.sendBatch(payload);
|
|
1488
1505
|
} catch (error) {
|
|
1489
|
-
console.error("[IK_TRACKER] Batch send failed
|
|
1490
|
-
|
|
1506
|
+
console.error("[IK_TRACKER] Batch send failed:", error.message);
|
|
1507
|
+
const isAuthError = error.message?.includes("401");
|
|
1508
|
+
if (!isAuthError) {
|
|
1509
|
+
console.log("[IK_TRACKER] Queuing for retry...");
|
|
1510
|
+
this.handleFailure(payload);
|
|
1511
|
+
} else {
|
|
1512
|
+
console.warn("[IK_TRACKER] Unauthorized: Please check your IK_FIREWALL_SECRET and License Key. Discarding batch.");
|
|
1513
|
+
}
|
|
1491
1514
|
} finally {
|
|
1492
1515
|
this.flushInProgress = false;
|
|
1493
1516
|
}
|
|
@@ -1496,6 +1519,9 @@ var UsageTracker = class {
|
|
|
1496
1519
|
const baseUrl = this.config.get("centralReportEndpoint") || "https://ik-firewall.vercel.app";
|
|
1497
1520
|
const endpoint = `${baseUrl.replace(/\/$/, "")}/api/v1/report`;
|
|
1498
1521
|
const hmacSecret = this.config.get("hmacSecret") || process.env.IK_FIREWALL_SECRET;
|
|
1522
|
+
if (process.env.IK_FIREWALL_DISABLED === "true" || process.env.NEXT_PUBLIC_IK_FIREWALL_DISABLED === "true") {
|
|
1523
|
+
return;
|
|
1524
|
+
}
|
|
1499
1525
|
if (hmacSecret) {
|
|
1500
1526
|
try {
|
|
1501
1527
|
const crypto = typeof window === "undefined" ? (await import("crypto")).default : null;
|
|
@@ -1516,6 +1542,16 @@ var UsageTracker = class {
|
|
|
1516
1542
|
if (!response.ok) {
|
|
1517
1543
|
throw new Error(`HTTP Error: ${response.status} ${response.statusText}`);
|
|
1518
1544
|
}
|
|
1545
|
+
try {
|
|
1546
|
+
const data = await response.json();
|
|
1547
|
+
if (data && (data.status === "blocked" || data.billingStatus === "blocked")) {
|
|
1548
|
+
this.config.setBlockedStatus(payload.instanceId, true);
|
|
1549
|
+
console.warn(`[IK_TRACKER] \u{1F6E1}\uFE0F Kill-Switch triggered for ${payload.instanceId}: Subscription inactive/blocked.`);
|
|
1550
|
+
} else if (data && (data.status === "active" || data.billingStatus === "active" || data.status === "trial")) {
|
|
1551
|
+
this.config.setBlockedStatus(payload.instanceId, false);
|
|
1552
|
+
}
|
|
1553
|
+
} catch (e) {
|
|
1554
|
+
}
|
|
1519
1555
|
this.hooks?.onFlushSuccess?.(payload);
|
|
1520
1556
|
}
|
|
1521
1557
|
async handleFailure(payload) {
|
|
@@ -1818,16 +1854,11 @@ var IKFirewallCore = class _IKFirewallCore {
|
|
|
1818
1854
|
}
|
|
1819
1855
|
if (instanceId) {
|
|
1820
1856
|
this.configManager.ensureInstanceConfig(instanceId);
|
|
1821
|
-
this.configManager.syncRemoteConfig(instanceId).catch((err) => {
|
|
1822
|
-
console.warn("[IK_CORE] Heartbeat sync failed:", err);
|
|
1823
|
-
});
|
|
1824
1857
|
}
|
|
1825
1858
|
const mergedConfig = this.configManager.getMergedConfig(instanceId);
|
|
1826
|
-
if (instanceId && mergedConfig?.
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
return this.getEmptyMetrics();
|
|
1830
|
-
}
|
|
1859
|
+
if (instanceId && mergedConfig?.billingStatus === "blocked") {
|
|
1860
|
+
this.hooks?.onStatus?.("\u26A0\uFE0F [IK_FIREWALL] Subscription inactive. Optimization bypassed (Fail-Safe mode).");
|
|
1861
|
+
return this.getEmptyMetrics();
|
|
1831
1862
|
}
|
|
1832
1863
|
let auditProvider = this.localProvider;
|
|
1833
1864
|
let overrideProvider = null;
|