@anomira/node-sdk 0.2.0 → 0.2.2
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/README.md +25 -1
- package/dist/index.cjs +1172 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +92 -6
- package/dist/index.d.ts +92 -6
- package/dist/index.js +1172 -18
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -78,6 +78,43 @@ interface AnomiraConfig {
|
|
|
78
78
|
* Default: reads X-Forwarded-For → X-Real-IP → socket.remoteAddress
|
|
79
79
|
*/
|
|
80
80
|
getIp?: (req: unknown) => string;
|
|
81
|
+
/**
|
|
82
|
+
* Invisible security — automatic blocking from Anomira's community
|
|
83
|
+
* threat intelligence network.
|
|
84
|
+
*
|
|
85
|
+
* When enabled (the default), the SDK periodically fetches high-confidence
|
|
86
|
+
* attacker IPs from the Anomira network — IPs that have been seen attacking
|
|
87
|
+
* multiple customers — and blocks them automatically, without any manual
|
|
88
|
+
* decision required.
|
|
89
|
+
*
|
|
90
|
+
* This is the "invisible" part: your API is protected from known bad actors
|
|
91
|
+
* the moment they appear in the network, before they even reach your handlers.
|
|
92
|
+
*
|
|
93
|
+
* Set `enabled: false` to disable auto-blocking and use threat data for
|
|
94
|
+
* alerting only (the data is still fetched and logged).
|
|
95
|
+
*/
|
|
96
|
+
autoBlock?: {
|
|
97
|
+
/**
|
|
98
|
+
* Whether to automatically block IPs from the community threat network.
|
|
99
|
+
* @default true
|
|
100
|
+
*/
|
|
101
|
+
enabled?: boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Minimum community confidence score (0-100) to trigger an auto-block.
|
|
104
|
+
* Only IPs above this threshold are blocked automatically.
|
|
105
|
+
*
|
|
106
|
+
* @default 85
|
|
107
|
+
*
|
|
108
|
+
* Guidance:
|
|
109
|
+
* 85 (default) — confirmed malicious across multiple customers, very low false-positive risk
|
|
110
|
+
* 70 — broader coverage, slightly higher false-positive risk
|
|
111
|
+
* 95 — maximum precision, only the most confirmed threats
|
|
112
|
+
*
|
|
113
|
+
* Do not set below 60 — scores below that reflect limited data and carry
|
|
114
|
+
* meaningful false-positive risk.
|
|
115
|
+
*/
|
|
116
|
+
communityThreshold?: number;
|
|
117
|
+
};
|
|
81
118
|
}
|
|
82
119
|
interface SdkEvent {
|
|
83
120
|
name: string;
|
|
@@ -150,22 +187,41 @@ interface FirewallRule {
|
|
|
150
187
|
*/
|
|
151
188
|
declare class AnomiraClient {
|
|
152
189
|
#private;
|
|
153
|
-
readonly config: Required<Omit<AnomiraConfig, "getUserId" | "getIp" | "detect">> & {
|
|
190
|
+
readonly config: Required<Omit<AnomiraConfig, "getUserId" | "getIp" | "detect" | "autoBlock">> & {
|
|
154
191
|
getUserId: NonNullable<AnomiraConfig["getUserId"]>;
|
|
155
192
|
getIp: NonNullable<AnomiraConfig["getIp"]>;
|
|
156
193
|
detect: Required<NonNullable<AnomiraConfig["detect"]>>;
|
|
157
194
|
captureConsole: boolean;
|
|
158
195
|
service: string;
|
|
196
|
+
autoBlock: Required<NonNullable<AnomiraConfig["autoBlock"]>>;
|
|
159
197
|
};
|
|
160
198
|
private readonly buffer;
|
|
161
199
|
private readonly logBuffer;
|
|
162
200
|
private logFlushTimer;
|
|
163
201
|
private blocklistTimer;
|
|
164
202
|
private firewallTimer;
|
|
203
|
+
private communityThreatTimer;
|
|
165
204
|
/** True when credentials are missing — all operations become no-ops. */
|
|
166
205
|
private disabled;
|
|
167
|
-
/** In-process cache of blocked IPs — refreshed every 60 s
|
|
206
|
+
/** In-process cache of manually blocked IPs — refreshed every 60 s. */
|
|
168
207
|
private blockedIpCache;
|
|
208
|
+
/** In-process cache of community threat IPs with their confidence scores.
|
|
209
|
+
* Populated from Anomira's federated threat network — IPs confirmed malicious
|
|
210
|
+
* across multiple customers. Refreshed every 60 s. */
|
|
211
|
+
private communityThreatCache;
|
|
212
|
+
/**
|
|
213
|
+
* Set of honeypot paths to intercept. When a request matches, the SDK returns
|
|
214
|
+
* a fake response instead of forwarding to the customer's route handlers.
|
|
215
|
+
* Synced from ingest every 60 s. Keys are lowercase path strings.
|
|
216
|
+
*/
|
|
217
|
+
private honeypotPaths;
|
|
218
|
+
/**
|
|
219
|
+
* Set of active canary token strings embedded in previously-served honeypot
|
|
220
|
+
* responses. When any of these appear in a request's Authorization header or
|
|
221
|
+
* body, a http.canary.triggered event is fired.
|
|
222
|
+
* Synced from ingest every 60 s (max 100 tokens, sliding 7-day window).
|
|
223
|
+
*/
|
|
224
|
+
private canaryTokenCache;
|
|
169
225
|
/** In-process cache of firewall rules with pre-compiled regex — refreshed every 60 s. */
|
|
170
226
|
private compiledRules;
|
|
171
227
|
private readonly _origLog;
|
|
@@ -184,8 +240,27 @@ declare class AnomiraClient {
|
|
|
184
240
|
* });
|
|
185
241
|
* ```
|
|
186
242
|
*/
|
|
187
|
-
/**
|
|
243
|
+
/**
|
|
244
|
+
* Returns true if the IP should be blocked. Synchronous — no network call.
|
|
245
|
+
*
|
|
246
|
+
* Checks two independent sources:
|
|
247
|
+
* 1. Manual blocklist — IPs explicitly blocked by the customer or via playbooks.
|
|
248
|
+
* 2. Community threats — IPs from Anomira's federated network whose confidence
|
|
249
|
+
* score meets the autoBlock.communityThreshold (default 85).
|
|
250
|
+
* Only active when autoBlock.enabled is true (the default).
|
|
251
|
+
*
|
|
252
|
+
* If a customer sets autoBlock.enabled = false, only the manual blocklist is checked.
|
|
253
|
+
*/
|
|
188
254
|
isBlocked(ip: string): boolean;
|
|
255
|
+
/**
|
|
256
|
+
* Returns the block reason for an IP — useful for logging or custom responses.
|
|
257
|
+
* Returns null if the IP is not blocked.
|
|
258
|
+
*/
|
|
259
|
+
blockReason(ip: string): {
|
|
260
|
+
source: "manual" | "community";
|
|
261
|
+
score?: number;
|
|
262
|
+
topAttack?: string;
|
|
263
|
+
} | null;
|
|
189
264
|
/**
|
|
190
265
|
* Fire-and-forget: report a blocked-IP attempt to the ingest server so the
|
|
191
266
|
* dashboard can show that the block is actively working.
|
|
@@ -206,7 +281,18 @@ declare class AnomiraClient {
|
|
|
206
281
|
rule: FirewallRule;
|
|
207
282
|
} | null;
|
|
208
283
|
track(eventName: string, data: {
|
|
209
|
-
|
|
284
|
+
/**
|
|
285
|
+
* Client IP address. Optional — when omitted or empty the SDK
|
|
286
|
+
* automatically reads it from the active request context set by the
|
|
287
|
+
* Express/Fastify middleware. This means developers calling track()
|
|
288
|
+
* inside a request handler get the correct IP for free, with no extra
|
|
289
|
+
* configuration required.
|
|
290
|
+
*
|
|
291
|
+
* Only pass this explicitly when calling track() outside a request
|
|
292
|
+
* context (e.g. from a background job or a webhook handler that has
|
|
293
|
+
* the IP available separately).
|
|
294
|
+
*/
|
|
295
|
+
ip?: string;
|
|
210
296
|
userId?: string;
|
|
211
297
|
meta?: Record<string, unknown>;
|
|
212
298
|
}): void;
|
|
@@ -223,7 +309,7 @@ declare class AnomiraClient {
|
|
|
223
309
|
* ```
|
|
224
310
|
*/
|
|
225
311
|
trackLogin(data: {
|
|
226
|
-
ip
|
|
312
|
+
ip?: string;
|
|
227
313
|
userId: string;
|
|
228
314
|
meta?: Record<string, unknown>;
|
|
229
315
|
}): Promise<void>;
|
|
@@ -242,7 +328,7 @@ declare class AnomiraClient {
|
|
|
242
328
|
* ```
|
|
243
329
|
*/
|
|
244
330
|
trackPhoneAuth(data: {
|
|
245
|
-
ip
|
|
331
|
+
ip?: string;
|
|
246
332
|
userId: string;
|
|
247
333
|
phone: string;
|
|
248
334
|
meta?: Record<string, unknown>;
|
package/dist/index.d.ts
CHANGED
|
@@ -78,6 +78,43 @@ interface AnomiraConfig {
|
|
|
78
78
|
* Default: reads X-Forwarded-For → X-Real-IP → socket.remoteAddress
|
|
79
79
|
*/
|
|
80
80
|
getIp?: (req: unknown) => string;
|
|
81
|
+
/**
|
|
82
|
+
* Invisible security — automatic blocking from Anomira's community
|
|
83
|
+
* threat intelligence network.
|
|
84
|
+
*
|
|
85
|
+
* When enabled (the default), the SDK periodically fetches high-confidence
|
|
86
|
+
* attacker IPs from the Anomira network — IPs that have been seen attacking
|
|
87
|
+
* multiple customers — and blocks them automatically, without any manual
|
|
88
|
+
* decision required.
|
|
89
|
+
*
|
|
90
|
+
* This is the "invisible" part: your API is protected from known bad actors
|
|
91
|
+
* the moment they appear in the network, before they even reach your handlers.
|
|
92
|
+
*
|
|
93
|
+
* Set `enabled: false` to disable auto-blocking and use threat data for
|
|
94
|
+
* alerting only (the data is still fetched and logged).
|
|
95
|
+
*/
|
|
96
|
+
autoBlock?: {
|
|
97
|
+
/**
|
|
98
|
+
* Whether to automatically block IPs from the community threat network.
|
|
99
|
+
* @default true
|
|
100
|
+
*/
|
|
101
|
+
enabled?: boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Minimum community confidence score (0-100) to trigger an auto-block.
|
|
104
|
+
* Only IPs above this threshold are blocked automatically.
|
|
105
|
+
*
|
|
106
|
+
* @default 85
|
|
107
|
+
*
|
|
108
|
+
* Guidance:
|
|
109
|
+
* 85 (default) — confirmed malicious across multiple customers, very low false-positive risk
|
|
110
|
+
* 70 — broader coverage, slightly higher false-positive risk
|
|
111
|
+
* 95 — maximum precision, only the most confirmed threats
|
|
112
|
+
*
|
|
113
|
+
* Do not set below 60 — scores below that reflect limited data and carry
|
|
114
|
+
* meaningful false-positive risk.
|
|
115
|
+
*/
|
|
116
|
+
communityThreshold?: number;
|
|
117
|
+
};
|
|
81
118
|
}
|
|
82
119
|
interface SdkEvent {
|
|
83
120
|
name: string;
|
|
@@ -150,22 +187,41 @@ interface FirewallRule {
|
|
|
150
187
|
*/
|
|
151
188
|
declare class AnomiraClient {
|
|
152
189
|
#private;
|
|
153
|
-
readonly config: Required<Omit<AnomiraConfig, "getUserId" | "getIp" | "detect">> & {
|
|
190
|
+
readonly config: Required<Omit<AnomiraConfig, "getUserId" | "getIp" | "detect" | "autoBlock">> & {
|
|
154
191
|
getUserId: NonNullable<AnomiraConfig["getUserId"]>;
|
|
155
192
|
getIp: NonNullable<AnomiraConfig["getIp"]>;
|
|
156
193
|
detect: Required<NonNullable<AnomiraConfig["detect"]>>;
|
|
157
194
|
captureConsole: boolean;
|
|
158
195
|
service: string;
|
|
196
|
+
autoBlock: Required<NonNullable<AnomiraConfig["autoBlock"]>>;
|
|
159
197
|
};
|
|
160
198
|
private readonly buffer;
|
|
161
199
|
private readonly logBuffer;
|
|
162
200
|
private logFlushTimer;
|
|
163
201
|
private blocklistTimer;
|
|
164
202
|
private firewallTimer;
|
|
203
|
+
private communityThreatTimer;
|
|
165
204
|
/** True when credentials are missing — all operations become no-ops. */
|
|
166
205
|
private disabled;
|
|
167
|
-
/** In-process cache of blocked IPs — refreshed every 60 s
|
|
206
|
+
/** In-process cache of manually blocked IPs — refreshed every 60 s. */
|
|
168
207
|
private blockedIpCache;
|
|
208
|
+
/** In-process cache of community threat IPs with their confidence scores.
|
|
209
|
+
* Populated from Anomira's federated threat network — IPs confirmed malicious
|
|
210
|
+
* across multiple customers. Refreshed every 60 s. */
|
|
211
|
+
private communityThreatCache;
|
|
212
|
+
/**
|
|
213
|
+
* Set of honeypot paths to intercept. When a request matches, the SDK returns
|
|
214
|
+
* a fake response instead of forwarding to the customer's route handlers.
|
|
215
|
+
* Synced from ingest every 60 s. Keys are lowercase path strings.
|
|
216
|
+
*/
|
|
217
|
+
private honeypotPaths;
|
|
218
|
+
/**
|
|
219
|
+
* Set of active canary token strings embedded in previously-served honeypot
|
|
220
|
+
* responses. When any of these appear in a request's Authorization header or
|
|
221
|
+
* body, a http.canary.triggered event is fired.
|
|
222
|
+
* Synced from ingest every 60 s (max 100 tokens, sliding 7-day window).
|
|
223
|
+
*/
|
|
224
|
+
private canaryTokenCache;
|
|
169
225
|
/** In-process cache of firewall rules with pre-compiled regex — refreshed every 60 s. */
|
|
170
226
|
private compiledRules;
|
|
171
227
|
private readonly _origLog;
|
|
@@ -184,8 +240,27 @@ declare class AnomiraClient {
|
|
|
184
240
|
* });
|
|
185
241
|
* ```
|
|
186
242
|
*/
|
|
187
|
-
/**
|
|
243
|
+
/**
|
|
244
|
+
* Returns true if the IP should be blocked. Synchronous — no network call.
|
|
245
|
+
*
|
|
246
|
+
* Checks two independent sources:
|
|
247
|
+
* 1. Manual blocklist — IPs explicitly blocked by the customer or via playbooks.
|
|
248
|
+
* 2. Community threats — IPs from Anomira's federated network whose confidence
|
|
249
|
+
* score meets the autoBlock.communityThreshold (default 85).
|
|
250
|
+
* Only active when autoBlock.enabled is true (the default).
|
|
251
|
+
*
|
|
252
|
+
* If a customer sets autoBlock.enabled = false, only the manual blocklist is checked.
|
|
253
|
+
*/
|
|
188
254
|
isBlocked(ip: string): boolean;
|
|
255
|
+
/**
|
|
256
|
+
* Returns the block reason for an IP — useful for logging or custom responses.
|
|
257
|
+
* Returns null if the IP is not blocked.
|
|
258
|
+
*/
|
|
259
|
+
blockReason(ip: string): {
|
|
260
|
+
source: "manual" | "community";
|
|
261
|
+
score?: number;
|
|
262
|
+
topAttack?: string;
|
|
263
|
+
} | null;
|
|
189
264
|
/**
|
|
190
265
|
* Fire-and-forget: report a blocked-IP attempt to the ingest server so the
|
|
191
266
|
* dashboard can show that the block is actively working.
|
|
@@ -206,7 +281,18 @@ declare class AnomiraClient {
|
|
|
206
281
|
rule: FirewallRule;
|
|
207
282
|
} | null;
|
|
208
283
|
track(eventName: string, data: {
|
|
209
|
-
|
|
284
|
+
/**
|
|
285
|
+
* Client IP address. Optional — when omitted or empty the SDK
|
|
286
|
+
* automatically reads it from the active request context set by the
|
|
287
|
+
* Express/Fastify middleware. This means developers calling track()
|
|
288
|
+
* inside a request handler get the correct IP for free, with no extra
|
|
289
|
+
* configuration required.
|
|
290
|
+
*
|
|
291
|
+
* Only pass this explicitly when calling track() outside a request
|
|
292
|
+
* context (e.g. from a background job or a webhook handler that has
|
|
293
|
+
* the IP available separately).
|
|
294
|
+
*/
|
|
295
|
+
ip?: string;
|
|
210
296
|
userId?: string;
|
|
211
297
|
meta?: Record<string, unknown>;
|
|
212
298
|
}): void;
|
|
@@ -223,7 +309,7 @@ declare class AnomiraClient {
|
|
|
223
309
|
* ```
|
|
224
310
|
*/
|
|
225
311
|
trackLogin(data: {
|
|
226
|
-
ip
|
|
312
|
+
ip?: string;
|
|
227
313
|
userId: string;
|
|
228
314
|
meta?: Record<string, unknown>;
|
|
229
315
|
}): Promise<void>;
|
|
@@ -242,7 +328,7 @@ declare class AnomiraClient {
|
|
|
242
328
|
* ```
|
|
243
329
|
*/
|
|
244
330
|
trackPhoneAuth(data: {
|
|
245
|
-
ip
|
|
331
|
+
ip?: string;
|
|
246
332
|
userId: string;
|
|
247
333
|
phone: string;
|
|
248
334
|
meta?: Record<string, unknown>;
|