devn-bot-detector-server 0.1.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.
@@ -0,0 +1,258 @@
1
+ import { SiteInfo, SessionData, RateLimitResult, RiskResult, Telemetry, RequestContext, RiskReason, RiskLevel, RiskDecision, AnalyzeRequest, RiskConfig, TokenRevocationStore, CreateSessionRequest, CreateSessionResponse, RiskTokenPayload, VerifyRiskTokenOptions } from 'devn-bot-detector-core';
2
+ export { API_PATHS, BotDetectorError, RequestContext, RiskDecision, RiskResult, RiskTokenPayload, SITE_KEY_HEADER, SessionData, SiteInfo, Telemetry, TokenRevocationStore, VerifyRiskTokenOptions } from 'devn-bot-detector-core';
3
+
4
+ interface SiteResolver {
5
+ resolveSite(siteKey: string): Promise<SiteInfo | null>;
6
+ }
7
+ interface SessionStore {
8
+ create(session: SessionData): Promise<void>;
9
+ get(sessionId: string): Promise<SessionData | null>;
10
+ update(session: SessionData): Promise<void>;
11
+ invalidate(sessionId: string): Promise<void>;
12
+ }
13
+ interface RateLimiter {
14
+ check(key: string, limit: number, windowMs: number): RateLimitResult | Promise<RateLimitResult>;
15
+ }
16
+ interface EventSink {
17
+ onAnalysis?(result: RiskResult): Promise<void> | void;
18
+ onSessionCreated?(session: SessionData): Promise<void> | void;
19
+ onError?(error: {
20
+ code: string;
21
+ message: string;
22
+ requestId: string;
23
+ }): Promise<void> | void;
24
+ }
25
+ /** Minimal duck-typed Redis interface compatible with ioredis, @redis/client, upstash, etc. */
26
+ interface RedisLikeClient {
27
+ get(key: string): Promise<string | null>;
28
+ set(key: string, value: string, ...args: unknown[]): Promise<unknown>;
29
+ del(key: string): Promise<unknown>;
30
+ eval?(script: string, numkeys: number, ...args: (string | number)[]): Promise<unknown>;
31
+ }
32
+
33
+ interface RiskInput {
34
+ readonly telemetry: Telemetry;
35
+ readonly request: RequestContext;
36
+ readonly sessionAgeMs: number;
37
+ readonly sequence: number;
38
+ readonly action?: string;
39
+ readonly metadata?: Record<string, unknown>;
40
+ }
41
+ interface RiskEvaluation {
42
+ readonly score: number;
43
+ readonly confidence: number;
44
+ readonly riskLevel: RiskLevel;
45
+ readonly decision?: RiskDecision;
46
+ readonly internalReasons: RiskReason[];
47
+ /** Optional additive risk from custom scoring (0–100 contribution scale). */
48
+ readonly risk?: number;
49
+ }
50
+ type Detector = (input: RiskInput) => RiskReason[];
51
+ /** Automation indicators — never decisive alone. */
52
+ declare const AutomationDetector: Detector;
53
+ declare const HeadlessAdvancedDetector: Detector;
54
+ declare const EntropyDetector: Detector;
55
+ declare const ActionRiskDetector: Detector;
56
+ declare const VelocityDetector: Detector;
57
+ declare const TimingDetector: Detector;
58
+ declare const InteractionDetector: Detector;
59
+ declare const BrowserConsistencyDetector: Detector;
60
+ declare const SessionDetector: Detector;
61
+ declare const DEFAULT_DETECTORS: Detector[];
62
+ interface RiskEngineOptions {
63
+ readonly detectors?: Detector[];
64
+ readonly detectorWeights?: Record<string, number>;
65
+ }
66
+ declare class RiskEngine {
67
+ private readonly detectors;
68
+ private readonly weights;
69
+ constructor(options?: Detector[] | RiskEngineOptions);
70
+ evaluate(input: RiskInput): RiskEvaluation;
71
+ }
72
+
73
+ interface ServerOptions {
74
+ readonly secret: string;
75
+ readonly sessionDuration?: number;
76
+ readonly riskThresholds?: Partial<RiskConfig>;
77
+ readonly actionThresholds?: Record<string, Partial<RiskConfig>>;
78
+ readonly ipAllowlist?: readonly string[];
79
+ readonly ipDenylist?: readonly string[];
80
+ readonly detectorWeights?: Record<string, number>;
81
+ readonly tokenRevocationStore?: TokenRevocationStore;
82
+ readonly enableRiskToken?: boolean;
83
+ readonly riskTokenDuration?: number;
84
+ readonly trustProxy?: boolean;
85
+ readonly debug?: boolean;
86
+ readonly siteResolver?: SiteResolver;
87
+ readonly sessionStore?: SessionStore;
88
+ readonly rateLimiter?: RateLimiter;
89
+ readonly eventSink?: EventSink;
90
+ readonly maxTelemetryBytes?: number;
91
+ readonly rateLimits?: {
92
+ readonly sitePerMinute?: number;
93
+ readonly sessionPerMinute?: number;
94
+ readonly ipPerMinute?: number;
95
+ };
96
+ readonly customScoring?: (input: RiskInput) => Partial<RiskEvaluation> | Promise<Partial<RiskEvaluation>>;
97
+ }
98
+ interface CreateSessionInput extends CreateSessionRequest {
99
+ readonly siteKey: string;
100
+ readonly request?: RequestContext;
101
+ }
102
+ interface AnalyzeInput extends AnalyzeRequest {
103
+ readonly siteKey: string;
104
+ readonly request?: RequestContext;
105
+ }
106
+ declare class BotDetectionServer {
107
+ private readonly sessionDuration;
108
+ private readonly thresholds;
109
+ private readonly actionThresholds?;
110
+ private readonly ipAllowlist;
111
+ private readonly ipDenylist;
112
+ private readonly tokenRevocationStore?;
113
+ private readonly enableRiskToken;
114
+ private readonly riskTokenDuration;
115
+ private readonly trustProxy;
116
+ private readonly debug;
117
+ private readonly maxTelemetryBytes;
118
+ private readonly siteResolver;
119
+ private readonly sessionStore;
120
+ private readonly rateLimiter;
121
+ private readonly eventSink?;
122
+ private readonly tokens;
123
+ private readonly engine;
124
+ private readonly customScoring?;
125
+ private readonly rateLimits;
126
+ constructor(options: ServerOptions);
127
+ getSite(siteKey: string): Promise<SiteInfo | null>;
128
+ validateHostname(hostname: string, site: SiteInfo, request?: RequestContext): boolean;
129
+ createSession(input: CreateSessionInput): Promise<CreateSessionResponse>;
130
+ analyze(input: AnalyzeInput): Promise<RiskResult>;
131
+ calculateRisk(input: RiskInput): Promise<RiskEvaluation>;
132
+ createRiskToken(payload: RiskTokenPayload): string;
133
+ verifyRiskToken(token: string, options?: VerifyRiskTokenOptions): RiskTokenPayload | null;
134
+ /**
135
+ * Validates risk token and consumes it (one-time use) if tokenRevocationStore is configured.
136
+ * Throws TOKEN_ALREADY_USED if already consumed or MALFORMED_REQUEST if invalid/expired.
137
+ */
138
+ consumeRiskToken(token: string, options?: VerifyRiskTokenOptions): Promise<RiskTokenPayload>;
139
+ private resolveActiveSite;
140
+ private assertRateLimits;
141
+ private resolveIp;
142
+ private normalizeRequest;
143
+ }
144
+
145
+ declare function secureId(prefix: string, bytes?: number): string;
146
+ /** In-memory site resolver for development/testing only. */
147
+ declare class MemorySiteResolver implements SiteResolver {
148
+ private readonly sites;
149
+ constructor(entries?: Array<{
150
+ siteKey: string;
151
+ site: SiteInfo;
152
+ }>);
153
+ set(siteKey: string, site: SiteInfo): void;
154
+ resolveSite(siteKey: string): Promise<SiteInfo | null>;
155
+ }
156
+ /** In-memory session store for development/testing only. */
157
+ declare class MemorySessionStore implements SessionStore {
158
+ private readonly sessions;
159
+ create(session: SessionData): Promise<void>;
160
+ get(sessionId: string): Promise<SessionData | null>;
161
+ update(session: SessionData): Promise<void>;
162
+ invalidate(sessionId: string): Promise<void>;
163
+ }
164
+ /** In-memory token revocation store for single-instance / dev usage. */
165
+ declare class MemoryTokenRevocationStore implements TokenRevocationStore {
166
+ private readonly revoked;
167
+ isRevoked(tokenId: string): boolean;
168
+ revoke(tokenId: string, ttlMs: number): void;
169
+ }
170
+
171
+ /** Simple in-memory sliding-window rate limiter (dev/default). */
172
+ declare class MemoryRateLimiter implements RateLimiter {
173
+ private readonly buckets;
174
+ check(key: string, limit: number, windowMs: number): RateLimitResult;
175
+ /** Best-effort cleanup for long-running processes. */
176
+ prune(): void;
177
+ }
178
+
179
+ declare class TokenManager {
180
+ private readonly secret;
181
+ constructor(secret: string);
182
+ createRiskToken(payload: RiskTokenPayload): string;
183
+ verifyRiskToken(token: string, options?: VerifyRiskTokenOptions): RiskTokenPayload | null;
184
+ }
185
+
186
+ interface RedisSessionStoreOptions {
187
+ readonly prefix?: string;
188
+ readonly defaultTtlSeconds?: number;
189
+ }
190
+ /** Production Redis Session Store with automatic TTL expiry. */
191
+ declare class RedisSessionStore implements SessionStore {
192
+ private readonly client;
193
+ private readonly prefix;
194
+ private readonly defaultTtl;
195
+ constructor(client: RedisLikeClient, options?: RedisSessionStoreOptions);
196
+ private key;
197
+ create(session: SessionData): Promise<void>;
198
+ get(sessionId: string): Promise<SessionData | null>;
199
+ update(session: SessionData): Promise<void>;
200
+ invalidate(sessionId: string): Promise<void>;
201
+ }
202
+ interface RedisRateLimiterOptions {
203
+ readonly prefix?: string;
204
+ }
205
+ /** Production Redis Rate Limiter with atomic INCR + EXPIRE via Lua or pipeline. */
206
+ declare class RedisRateLimiter implements RateLimiter {
207
+ private readonly client;
208
+ private readonly prefix;
209
+ constructor(client: RedisLikeClient, options?: RedisRateLimiterOptions);
210
+ check(key: string, limit: number, windowMs: number): Promise<RateLimitResult>;
211
+ }
212
+ interface RedisTokenRevocationStoreOptions {
213
+ readonly prefix?: string;
214
+ }
215
+ /** Production Redis token revocation store for one-time token consumption / replay prevention. */
216
+ declare class RedisTokenRevocationStore implements TokenRevocationStore {
217
+ private readonly client;
218
+ private readonly prefix;
219
+ constructor(client: RedisLikeClient, options?: RedisTokenRevocationStoreOptions);
220
+ isRevoked(tokenId: string): Promise<boolean>;
221
+ revoke(tokenId: string, ttlMs: number): Promise<void>;
222
+ }
223
+
224
+ interface FrameworkRequestLike {
225
+ headers?: Record<string, string | string[] | undefined>;
226
+ header?(name: string): string | undefined;
227
+ get?(name: string): string | undefined;
228
+ body?: unknown;
229
+ ip?: string;
230
+ }
231
+ interface FrameworkResponseLike {
232
+ status(code: number): this;
233
+ json(body: unknown): void;
234
+ }
235
+ interface TokenGuardOptions extends VerifyRiskTokenOptions {
236
+ /** If true, the token is consumed (one-time use, preventing replay attacks). Defaults to false. */
237
+ readonly consume?: boolean;
238
+ /** Header to read the token from. Defaults to 'x-risk-token'. */
239
+ readonly headerName?: string;
240
+ /** Fallback property to read the token from request body. Defaults to 'riskToken'. */
241
+ readonly bodyField?: string;
242
+ }
243
+ /**
244
+ * Universal helper to extract and verify or consume a risk token from any incoming HTTP request.
245
+ * Useful for Next.js Server Actions, Nuxt, SvelteKit, Remix, NestJS, Fastify, Express, and Hono.
246
+ */
247
+ declare function verifyRequestRiskToken(server: BotDetectionServer, request: FrameworkRequestLike, options?: TokenGuardOptions): Promise<RiskTokenPayload>;
248
+ /** Express / Connect helper creating ready-to-mount route handlers and guards. */
249
+ declare function createExpressBotDetector(server: BotDetectionServer): {
250
+ /** Route handler for POST /v1/session */
251
+ sessionHandler: (req: any, res: any) => Promise<void>;
252
+ /** Route handler for POST /v1/analyze */
253
+ analyzeHandler: (req: any, res: any) => Promise<void>;
254
+ /** Middleware protecting sensitive routes with risk token verification */
255
+ requireRiskToken: (options?: TokenGuardOptions) => (req: any, res: any, next: any) => Promise<void>;
256
+ };
257
+
258
+ export { ActionRiskDetector, type AnalyzeInput, AutomationDetector, BotDetectionServer, BrowserConsistencyDetector, type CreateSessionInput, DEFAULT_DETECTORS, type Detector, EntropyDetector, type EventSink, type FrameworkRequestLike, type FrameworkResponseLike, HeadlessAdvancedDetector, InteractionDetector, MemoryRateLimiter, MemorySessionStore, MemorySiteResolver, MemoryTokenRevocationStore, type RateLimiter, type RedisLikeClient, RedisRateLimiter, type RedisRateLimiterOptions, RedisSessionStore, type RedisSessionStoreOptions, RedisTokenRevocationStore, type RedisTokenRevocationStoreOptions, RiskEngine, type RiskEngineOptions, type RiskEvaluation, type RiskInput, type ServerOptions, SessionDetector, type SessionStore, type SiteResolver, TimingDetector, type TokenGuardOptions, TokenManager, VelocityDetector, createExpressBotDetector, secureId, verifyRequestRiskToken };