@arcis/node 1.3.0 → 1.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/core/{index.d.mts → constants.d.ts} +21 -70
- package/dist/core/constants.d.ts.map +1 -0
- package/dist/core/errors.d.ts +53 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/index.d.ts +6 -168
- package/dist/core/index.d.ts.map +1 -0
- package/dist/{types-BOkx5YJc.d.mts → core/types.d.ts} +27 -30
- package/dist/core/types.d.ts.map +1 -0
- package/dist/index.d.ts +71 -166
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +56 -3
- package/dist/index.mjs.map +1 -1
- package/dist/logging/index.d.ts +4 -36
- package/dist/logging/index.d.ts.map +1 -0
- package/dist/logging/{index.d.mts → redactor.d.ts} +5 -9
- package/dist/logging/redactor.d.ts.map +1 -0
- package/dist/middleware/bot-detection.d.ts +86 -0
- package/dist/middleware/bot-detection.d.ts.map +1 -0
- package/dist/middleware/cookies.d.ts +48 -0
- package/dist/middleware/cookies.d.ts.map +1 -0
- package/dist/middleware/cors.d.ts +65 -0
- package/dist/middleware/cors.d.ts.map +1 -0
- package/dist/middleware/csrf.d.ts +109 -0
- package/dist/middleware/csrf.d.ts.map +1 -0
- package/dist/middleware/error-handler.d.ts +43 -0
- package/dist/middleware/error-handler.d.ts.map +1 -0
- package/dist/middleware/headers.d.ts +29 -0
- package/dist/middleware/headers.d.ts.map +1 -0
- package/dist/middleware/hpp.d.ts +56 -0
- package/dist/middleware/hpp.d.ts.map +1 -0
- package/dist/middleware/index.d.ts +16 -3
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +6 -1
- package/dist/middleware/index.js.map +1 -1
- package/dist/middleware/index.mjs +6 -1
- package/dist/middleware/index.mjs.map +1 -1
- package/dist/middleware/main.d.ts +40 -0
- package/dist/middleware/main.d.ts.map +1 -0
- package/dist/middleware/rate-limit-sliding.d.ts +46 -0
- package/dist/middleware/rate-limit-sliding.d.ts.map +1 -0
- package/dist/middleware/rate-limit-token.d.ts +51 -0
- package/dist/middleware/rate-limit-token.d.ts.map +1 -0
- package/dist/middleware/rate-limit.d.ts +34 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -0
- package/dist/sanitizers/command.d.ts +28 -0
- package/dist/sanitizers/command.d.ts.map +1 -0
- package/dist/sanitizers/encode.d.ts +46 -0
- package/dist/sanitizers/encode.d.ts.map +1 -0
- package/dist/sanitizers/headers.d.ts +46 -0
- package/dist/sanitizers/headers.d.ts.map +1 -0
- package/dist/sanitizers/index.d.ts +17 -22
- package/dist/sanitizers/index.d.ts.map +1 -0
- package/dist/sanitizers/jsonp.d.ts +34 -0
- package/dist/sanitizers/jsonp.d.ts.map +1 -0
- package/dist/sanitizers/nosql.d.ts +31 -0
- package/dist/sanitizers/nosql.d.ts.map +1 -0
- package/dist/sanitizers/path.d.ts +28 -0
- package/dist/sanitizers/path.d.ts.map +1 -0
- package/dist/sanitizers/pii.d.ts +80 -0
- package/dist/sanitizers/pii.d.ts.map +1 -0
- package/dist/sanitizers/prototype.d.ts +34 -0
- package/dist/sanitizers/prototype.d.ts.map +1 -0
- package/dist/sanitizers/sanitize.d.ts +51 -0
- package/dist/sanitizers/sanitize.d.ts.map +1 -0
- package/dist/sanitizers/sql.d.ts +28 -0
- package/dist/sanitizers/sql.d.ts.map +1 -0
- package/dist/sanitizers/ssti.d.ts +20 -0
- package/dist/sanitizers/ssti.d.ts.map +1 -0
- package/dist/sanitizers/utils.d.ts +19 -0
- package/dist/sanitizers/utils.d.ts.map +1 -0
- package/dist/sanitizers/xss.d.ts +35 -0
- package/dist/sanitizers/xss.d.ts.map +1 -0
- package/dist/sanitizers/xxe.d.ts +20 -0
- package/dist/sanitizers/xxe.d.ts.map +1 -0
- package/dist/stores/index.d.ts +6 -104
- package/dist/stores/index.d.ts.map +1 -0
- package/dist/stores/memory.d.ts +35 -0
- package/dist/stores/memory.d.ts.map +1 -0
- package/dist/stores/{index.d.mts → redis.d.ts} +6 -45
- package/dist/stores/redis.d.ts.map +1 -0
- package/dist/utils/duration.d.ts +34 -0
- package/dist/utils/duration.d.ts.map +1 -0
- package/dist/utils/fingerprint.d.ts +64 -0
- package/dist/utils/fingerprint.d.ts.map +1 -0
- package/dist/utils/index.d.ts +10 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +188 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/index.mjs +182 -0
- package/dist/utils/index.mjs.map +1 -0
- package/dist/utils/ip.d.ts +70 -0
- package/dist/utils/ip.d.ts.map +1 -0
- package/dist/validation/email.d.ts +82 -0
- package/dist/validation/email.d.ts.map +1 -0
- package/dist/validation/file.d.ts +90 -0
- package/dist/validation/file.d.ts.map +1 -0
- package/dist/validation/index.d.ts +10 -3
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/redirect.d.ts +64 -0
- package/dist/validation/redirect.d.ts.map +1 -0
- package/dist/validation/schema.d.ts +36 -0
- package/dist/validation/schema.d.ts.map +1 -0
- package/dist/validation/url.d.ts +65 -0
- package/dist/validation/url.d.ts.map +1 -0
- package/package.json +8 -6
- package/dist/encode-CrQCGlBq.d.mts +0 -484
- package/dist/encode-jl9sOwmA.d.ts +0 -484
- package/dist/index-BAhgn9V2.d.ts +0 -532
- package/dist/index-BGNKspqH.d.ts +0 -340
- package/dist/index-Cd02z-0j.d.mts +0 -340
- package/dist/index-DgJtWMSj.d.mts +0 -532
- package/dist/index.d.mts +0 -175
- package/dist/middleware/index.d.mts +0 -3
- package/dist/sanitizers/index.d.mts +0 -24
- package/dist/types-BOkx5YJc.d.ts +0 -279
- package/dist/validation/index.d.mts +0 -3
|
@@ -1,532 +0,0 @@
|
|
|
1
|
-
import { b as ArcisOptions, o as ArcisMiddlewareStack, A as ArcisFunction, e as RateLimitOptions, h as RateLimiterMiddleware, H as HeaderOptions, E as ErrorHandlerOptions } from './types-BOkx5YJc.mjs';
|
|
2
|
-
import { RequestHandler, Request, Response, NextFunction } from 'express';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @module @arcis/node/middleware/main
|
|
6
|
-
* Main arcis() middleware factory
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Create Arcis middleware with all protections enabled.
|
|
11
|
-
*
|
|
12
|
-
* @param options - Configuration options
|
|
13
|
-
* @returns Array of Express middleware
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* // Full protection (recommended)
|
|
17
|
-
* app.use(arcis());
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* // Custom configuration
|
|
21
|
-
* app.use(arcis({
|
|
22
|
-
* rateLimit: { max: 50 },
|
|
23
|
-
* headers: { frameOptions: 'SAMEORIGIN' }
|
|
24
|
-
* }));
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* // Disable specific features
|
|
28
|
-
* app.use(arcis({
|
|
29
|
-
* rateLimit: false,
|
|
30
|
-
* sanitize: { sql: false }
|
|
31
|
-
* }));
|
|
32
|
-
*
|
|
33
|
-
* @example
|
|
34
|
-
* // Cleanup on shutdown
|
|
35
|
-
* const middleware = arcis();
|
|
36
|
-
* app.use(middleware);
|
|
37
|
-
* process.on('SIGTERM', () => middleware.close());
|
|
38
|
-
*/
|
|
39
|
-
declare function arcis(options?: ArcisOptions): ArcisMiddlewareStack;
|
|
40
|
-
declare const arcisWithMethods: ArcisFunction;
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* @module @arcis/node/middleware/rate-limit
|
|
44
|
-
* Rate limiting middleware
|
|
45
|
-
*/
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Create Express middleware for rate limiting.
|
|
49
|
-
*
|
|
50
|
-
* @param options - Rate limit configuration
|
|
51
|
-
* @returns Express middleware with cleanup method
|
|
52
|
-
*
|
|
53
|
-
* @example
|
|
54
|
-
* app.use(createRateLimiter({ max: 100, windowMs: 60000 }));
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* // Skip rate limiting for certain routes
|
|
58
|
-
* app.use(createRateLimiter({
|
|
59
|
-
* max: 50,
|
|
60
|
-
* skip: (req) => req.path === '/health'
|
|
61
|
-
* }));
|
|
62
|
-
*
|
|
63
|
-
* @example
|
|
64
|
-
* // Cleanup on shutdown
|
|
65
|
-
* const limiter = createRateLimiter();
|
|
66
|
-
* app.use(limiter);
|
|
67
|
-
* process.on('SIGTERM', () => limiter.close());
|
|
68
|
-
*/
|
|
69
|
-
declare function createRateLimiter(options?: RateLimitOptions): RateLimiterMiddleware;
|
|
70
|
-
/**
|
|
71
|
-
* Alias for createRateLimiter
|
|
72
|
-
* @see createRateLimiter
|
|
73
|
-
*/
|
|
74
|
-
declare const rateLimit: typeof createRateLimiter;
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* @module @arcis/node/middleware/rate-limit-sliding
|
|
78
|
-
* Sliding window rate limiting middleware.
|
|
79
|
-
*
|
|
80
|
-
* More accurate than fixed window — uses a weighted sum of the previous
|
|
81
|
-
* and current window to approximate a true sliding window.
|
|
82
|
-
*
|
|
83
|
-
* Algorithm:
|
|
84
|
-
* weight = (windowMs - elapsed) / windowMs
|
|
85
|
-
* count = (prevWindow * weight) + currentWindow
|
|
86
|
-
* allow = count < limit
|
|
87
|
-
*
|
|
88
|
-
* @example
|
|
89
|
-
* app.use(createSlidingWindowLimiter({ max: 100, window: '15m' }));
|
|
90
|
-
*/
|
|
91
|
-
|
|
92
|
-
interface SlidingWindowOptions {
|
|
93
|
-
/** Maximum requests per window. Default: 100 */
|
|
94
|
-
max?: number;
|
|
95
|
-
/** Window size in ms or duration string. Default: '1m' */
|
|
96
|
-
window?: string | number;
|
|
97
|
-
/** Error message when limit exceeded */
|
|
98
|
-
message?: string;
|
|
99
|
-
/** HTTP status code for rate limited responses. Default: 429 */
|
|
100
|
-
statusCode?: number;
|
|
101
|
-
/** Function to generate rate limit key from request */
|
|
102
|
-
keyGenerator?: (req: Request) => string;
|
|
103
|
-
/** Function to skip rate limiting for certain requests */
|
|
104
|
-
skip?: (req: Request) => boolean;
|
|
105
|
-
}
|
|
106
|
-
interface SlidingWindowMiddleware extends RequestHandler {
|
|
107
|
-
close: () => void;
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Create sliding window rate limiter middleware.
|
|
111
|
-
*
|
|
112
|
-
* @example
|
|
113
|
-
* // 100 requests per 15 minutes
|
|
114
|
-
* app.use(createSlidingWindowLimiter({ max: 100, window: '15m' }));
|
|
115
|
-
*
|
|
116
|
-
* @example
|
|
117
|
-
* // Strict API limit
|
|
118
|
-
* app.use('/api', createSlidingWindowLimiter({ max: 30, window: '1m' }));
|
|
119
|
-
*/
|
|
120
|
-
declare function createSlidingWindowLimiter(options?: SlidingWindowOptions): SlidingWindowMiddleware;
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* @module @arcis/node/middleware/rate-limit-token
|
|
124
|
-
* Token bucket rate limiting middleware.
|
|
125
|
-
*
|
|
126
|
-
* Allows burst traffic while enforcing an average rate.
|
|
127
|
-
* Tokens refill at a steady rate. Each request costs 1 token.
|
|
128
|
-
*
|
|
129
|
-
* Algorithm:
|
|
130
|
-
* tokens = min(capacity, tokens + elapsed * refillRate)
|
|
131
|
-
* if tokens >= cost: allow, subtract cost
|
|
132
|
-
* else: deny
|
|
133
|
-
*
|
|
134
|
-
* @example
|
|
135
|
-
* app.use(createTokenBucketLimiter({ capacity: 50, refillRate: 10 }));
|
|
136
|
-
*/
|
|
137
|
-
|
|
138
|
-
interface TokenBucketOptions {
|
|
139
|
-
/** Maximum tokens (burst size). Default: 100 */
|
|
140
|
-
capacity?: number;
|
|
141
|
-
/** Tokens added per second. Default: 10 */
|
|
142
|
-
refillRate?: number;
|
|
143
|
-
/** Tokens consumed per request. Default: 1 */
|
|
144
|
-
cost?: number;
|
|
145
|
-
/** Error message when limit exceeded */
|
|
146
|
-
message?: string;
|
|
147
|
-
/** HTTP status code for rate limited responses. Default: 429 */
|
|
148
|
-
statusCode?: number;
|
|
149
|
-
/** Function to generate rate limit key from request */
|
|
150
|
-
keyGenerator?: (req: Request) => string;
|
|
151
|
-
/** Function to skip rate limiting for certain requests */
|
|
152
|
-
skip?: (req: Request) => boolean;
|
|
153
|
-
}
|
|
154
|
-
interface TokenBucketMiddleware extends RequestHandler {
|
|
155
|
-
close: () => void;
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Create token bucket rate limiter middleware.
|
|
159
|
-
*
|
|
160
|
-
* @example
|
|
161
|
-
* // Allow bursts of 50, sustained rate of 10/sec
|
|
162
|
-
* app.use(createTokenBucketLimiter({ capacity: 50, refillRate: 10 }));
|
|
163
|
-
*
|
|
164
|
-
* @example
|
|
165
|
-
* // Strict API: 5 requests burst, 1/sec sustained
|
|
166
|
-
* app.use('/api/expensive', createTokenBucketLimiter({
|
|
167
|
-
* capacity: 5,
|
|
168
|
-
* refillRate: 1,
|
|
169
|
-
* }));
|
|
170
|
-
*/
|
|
171
|
-
declare function createTokenBucketLimiter(options?: TokenBucketOptions): TokenBucketMiddleware;
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* @module @arcis/node/middleware/headers
|
|
175
|
-
* Security headers middleware
|
|
176
|
-
*/
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Create Express middleware for security headers.
|
|
180
|
-
* Sets CSP, HSTS, X-Frame-Options, and other security headers.
|
|
181
|
-
*
|
|
182
|
-
* @param options - Header configuration
|
|
183
|
-
* @returns Express middleware
|
|
184
|
-
*
|
|
185
|
-
* @example
|
|
186
|
-
* app.use(createHeaders());
|
|
187
|
-
*
|
|
188
|
-
* @example
|
|
189
|
-
* app.use(createHeaders({
|
|
190
|
-
* frameOptions: 'SAMEORIGIN',
|
|
191
|
-
* contentSecurityPolicy: "default-src 'self'"
|
|
192
|
-
* }));
|
|
193
|
-
*/
|
|
194
|
-
declare function createHeaders(options?: HeaderOptions): RequestHandler;
|
|
195
|
-
/**
|
|
196
|
-
* Alias for createHeaders
|
|
197
|
-
* @see createHeaders
|
|
198
|
-
*/
|
|
199
|
-
declare const securityHeaders: typeof createHeaders;
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* @module @arcis/node/middleware/error-handler
|
|
203
|
-
* Production-safe error handler middleware
|
|
204
|
-
*/
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Create Express error handler that hides sensitive details in production.
|
|
208
|
-
*
|
|
209
|
-
* Prevents information leakage by:
|
|
210
|
-
* - Hiding stack traces in production
|
|
211
|
-
* - Hiding error messages unless explicitly exposed
|
|
212
|
-
* - Scrubbing database errors, connection strings, and internal IPs
|
|
213
|
-
*
|
|
214
|
-
* @param options - Error handler configuration (or boolean for isDev)
|
|
215
|
-
* @returns Express error handling middleware
|
|
216
|
-
*
|
|
217
|
-
* @example
|
|
218
|
-
* // Production mode (default) - hides error details
|
|
219
|
-
* app.use(errorHandler());
|
|
220
|
-
*
|
|
221
|
-
* @example
|
|
222
|
-
* // Development mode - shows error details and stack traces
|
|
223
|
-
* app.use(errorHandler({ isDev: true }));
|
|
224
|
-
*
|
|
225
|
-
* @example
|
|
226
|
-
* // With custom logger
|
|
227
|
-
* app.use(errorHandler({
|
|
228
|
-
* isDev: false,
|
|
229
|
-
* logger: arcis.logger()
|
|
230
|
-
* }));
|
|
231
|
-
*/
|
|
232
|
-
declare function errorHandler(options?: ErrorHandlerOptions | boolean): (err: Error, req: Request, res: Response, next: NextFunction) => void;
|
|
233
|
-
/**
|
|
234
|
-
* Alias for errorHandler
|
|
235
|
-
* @see errorHandler
|
|
236
|
-
*/
|
|
237
|
-
declare const createErrorHandler: typeof errorHandler;
|
|
238
|
-
|
|
239
|
-
/**
|
|
240
|
-
* @module @arcis/node/middleware/cors
|
|
241
|
-
* Safe CORS middleware with secure defaults
|
|
242
|
-
*/
|
|
243
|
-
|
|
244
|
-
/** CORS configuration options */
|
|
245
|
-
interface CorsOptions {
|
|
246
|
-
/**
|
|
247
|
-
* Allowed origins. Can be:
|
|
248
|
-
* - A string: exact match (e.g., 'https://example.com')
|
|
249
|
-
* - An array: whitelist of allowed origins
|
|
250
|
-
* - A RegExp: pattern match (use with care)
|
|
251
|
-
* - A function: custom validation `(origin) => boolean`
|
|
252
|
-
* - `true`: reflect the request origin (DANGEROUS — only for dev)
|
|
253
|
-
*
|
|
254
|
-
* Default: none (no origin allowed). You must explicitly set this.
|
|
255
|
-
*/
|
|
256
|
-
origin: string | string[] | RegExp | ((origin: string) => boolean) | true;
|
|
257
|
-
/** Allowed HTTP methods. Default: ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE'] */
|
|
258
|
-
methods?: string[];
|
|
259
|
-
/** Allowed headers. Default: ['Content-Type', 'Authorization'] */
|
|
260
|
-
allowedHeaders?: string[];
|
|
261
|
-
/** Headers exposed to the browser. Default: [] */
|
|
262
|
-
exposedHeaders?: string[];
|
|
263
|
-
/** Allow credentials (cookies, authorization headers). Default: false */
|
|
264
|
-
credentials?: boolean;
|
|
265
|
-
/** Preflight cache duration in seconds. Default: 600 (10 minutes) */
|
|
266
|
-
maxAge?: number;
|
|
267
|
-
/** Respond to preflight with 204 (no content). Default: true */
|
|
268
|
-
preflightContinue?: boolean;
|
|
269
|
-
}
|
|
270
|
-
/**
|
|
271
|
-
* Create safe CORS middleware.
|
|
272
|
-
*
|
|
273
|
-
* Unlike permissive CORS libraries, this enforces secure defaults:
|
|
274
|
-
* - No wildcard `*` when credentials are enabled
|
|
275
|
-
* - `null` origin is always blocked
|
|
276
|
-
* - `Vary: Origin` is always set for proper caching
|
|
277
|
-
* - You must explicitly configure allowed origins
|
|
278
|
-
*
|
|
279
|
-
* @param options - CORS configuration
|
|
280
|
-
* @returns Express middleware
|
|
281
|
-
*
|
|
282
|
-
* @example
|
|
283
|
-
* // Allow a single origin
|
|
284
|
-
* app.use(safeCors({ origin: 'https://myapp.com' }));
|
|
285
|
-
*
|
|
286
|
-
* @example
|
|
287
|
-
* // Allow multiple origins with credentials
|
|
288
|
-
* app.use(safeCors({
|
|
289
|
-
* origin: ['https://myapp.com', 'https://admin.myapp.com'],
|
|
290
|
-
* credentials: true,
|
|
291
|
-
* }));
|
|
292
|
-
*
|
|
293
|
-
* @example
|
|
294
|
-
* // Development: allow all (NOT for production)
|
|
295
|
-
* app.use(safeCors({ origin: true }));
|
|
296
|
-
*/
|
|
297
|
-
declare function safeCors(options: CorsOptions): RequestHandler;
|
|
298
|
-
/**
|
|
299
|
-
* Alias for safeCors
|
|
300
|
-
* @see safeCors
|
|
301
|
-
*/
|
|
302
|
-
declare const createCors: typeof safeCors;
|
|
303
|
-
|
|
304
|
-
/**
|
|
305
|
-
* @module @arcis/node/middleware/cookies
|
|
306
|
-
* Secure cookie defaults middleware
|
|
307
|
-
*/
|
|
308
|
-
|
|
309
|
-
/** Cookie security configuration */
|
|
310
|
-
interface SecureCookieOptions {
|
|
311
|
-
/** Force HttpOnly on all cookies. Default: true */
|
|
312
|
-
httpOnly?: boolean;
|
|
313
|
-
/** Force Secure flag (HTTPS only). Default: true in production, false in dev */
|
|
314
|
-
secure?: boolean;
|
|
315
|
-
/** SameSite attribute. Default: 'Lax' */
|
|
316
|
-
sameSite?: 'Strict' | 'Lax' | 'None' | false;
|
|
317
|
-
/** Override Path attribute. Default: undefined (keep original) */
|
|
318
|
-
path?: string;
|
|
319
|
-
}
|
|
320
|
-
/**
|
|
321
|
-
* Enforce secure defaults on a Set-Cookie header value.
|
|
322
|
-
*/
|
|
323
|
-
declare function enforceSecureCookie(cookieStr: string, options: Required<Omit<SecureCookieOptions, 'path'>> & {
|
|
324
|
-
path?: string;
|
|
325
|
-
}): string;
|
|
326
|
-
/**
|
|
327
|
-
* Create middleware that enforces secure cookie defaults.
|
|
328
|
-
*
|
|
329
|
-
* Intercepts Set-Cookie headers and adds missing security attributes:
|
|
330
|
-
* - HttpOnly: prevents JavaScript access (XSS cookie theft)
|
|
331
|
-
* - Secure: cookies only sent over HTTPS
|
|
332
|
-
* - SameSite: CSRF protection
|
|
333
|
-
*
|
|
334
|
-
* @param options - Cookie security configuration
|
|
335
|
-
* @returns Express middleware
|
|
336
|
-
*
|
|
337
|
-
* @example
|
|
338
|
-
* // Enforce defaults on all cookies
|
|
339
|
-
* app.use(secureCookieDefaults());
|
|
340
|
-
*
|
|
341
|
-
* @example
|
|
342
|
-
* // Strict SameSite for sensitive apps
|
|
343
|
-
* app.use(secureCookieDefaults({ sameSite: 'Strict' }));
|
|
344
|
-
*/
|
|
345
|
-
declare function secureCookieDefaults(options?: SecureCookieOptions): RequestHandler;
|
|
346
|
-
/**
|
|
347
|
-
* Alias for secureCookieDefaults
|
|
348
|
-
* @see secureCookieDefaults
|
|
349
|
-
*/
|
|
350
|
-
declare const createSecureCookies: typeof secureCookieDefaults;
|
|
351
|
-
|
|
352
|
-
/**
|
|
353
|
-
* @module @arcis/node/middleware/bot-detection
|
|
354
|
-
* Local-only bot detection using User-Agent and behavioral signals.
|
|
355
|
-
*
|
|
356
|
-
* Categorizes requests into bot types and allows/denies based on config.
|
|
357
|
-
* No cloud calls — everything runs locally.
|
|
358
|
-
*
|
|
359
|
-
* @example
|
|
360
|
-
* // Block automated tools, allow search engines
|
|
361
|
-
* app.use(botProtection({
|
|
362
|
-
* allow: ['SEARCH_ENGINE', 'SOCIAL', 'MONITORING'],
|
|
363
|
-
* deny: ['AUTOMATED', 'SCRAPER'],
|
|
364
|
-
* }));
|
|
365
|
-
*/
|
|
366
|
-
|
|
367
|
-
type BotCategory = 'SEARCH_ENGINE' | 'SOCIAL' | 'MONITORING' | 'AI_CRAWLER' | 'SCRAPER' | 'AUTOMATED' | 'UNKNOWN' | 'HUMAN';
|
|
368
|
-
interface BotDetectionResult {
|
|
369
|
-
/** Whether the request appears to be from a bot */
|
|
370
|
-
isBot: boolean;
|
|
371
|
-
/** Bot category */
|
|
372
|
-
category: BotCategory;
|
|
373
|
-
/** Matched bot name (e.g. 'Googlebot', 'curl') or null */
|
|
374
|
-
name: string | null;
|
|
375
|
-
/** Confidence score: 0-1 */
|
|
376
|
-
confidence: number;
|
|
377
|
-
/** Behavioral signals detected */
|
|
378
|
-
signals: string[];
|
|
379
|
-
}
|
|
380
|
-
interface BotProtectionOptions {
|
|
381
|
-
/** Categories to explicitly allow. Default: ['SEARCH_ENGINE', 'SOCIAL', 'MONITORING'] */
|
|
382
|
-
allow?: BotCategory[];
|
|
383
|
-
/** Categories to explicitly deny. Default: ['AUTOMATED'] */
|
|
384
|
-
deny?: BotCategory[];
|
|
385
|
-
/** Action for categories not in allow or deny. Default: 'allow' */
|
|
386
|
-
defaultAction?: 'allow' | 'deny';
|
|
387
|
-
/** HTTP status code for denied bots. Default: 403 */
|
|
388
|
-
statusCode?: number;
|
|
389
|
-
/** Error message for denied bots */
|
|
390
|
-
message?: string;
|
|
391
|
-
/** Enable behavioral signal detection. Default: true */
|
|
392
|
-
detectBehavior?: boolean;
|
|
393
|
-
/** Custom handler called on detection (instead of default deny response) */
|
|
394
|
-
onDetected?: (req: Request, res: Response, result: BotDetectionResult) => void;
|
|
395
|
-
}
|
|
396
|
-
/**
|
|
397
|
-
* Detect what kind of bot (if any) is making the request.
|
|
398
|
-
*
|
|
399
|
-
* @param req - HTTP request object
|
|
400
|
-
* @returns Detection result with category, name, confidence, and signals
|
|
401
|
-
*
|
|
402
|
-
* @example
|
|
403
|
-
* const result = detectBot(req);
|
|
404
|
-
* if (result.isBot && result.category === 'AUTOMATED') {
|
|
405
|
-
* // Block automated tools
|
|
406
|
-
* }
|
|
407
|
-
*/
|
|
408
|
-
declare function detectBot(req: Request): BotDetectionResult;
|
|
409
|
-
/**
|
|
410
|
-
* Create Express middleware for bot protection.
|
|
411
|
-
*
|
|
412
|
-
* @example
|
|
413
|
-
* // Block automated tools and scrapers
|
|
414
|
-
* app.use(botProtection({
|
|
415
|
-
* allow: ['SEARCH_ENGINE', 'SOCIAL', 'MONITORING'],
|
|
416
|
-
* deny: ['AUTOMATED', 'SCRAPER'],
|
|
417
|
-
* }));
|
|
418
|
-
*
|
|
419
|
-
* @example
|
|
420
|
-
* // Block everything except search engines
|
|
421
|
-
* app.use(botProtection({
|
|
422
|
-
* allow: ['SEARCH_ENGINE'],
|
|
423
|
-
* defaultAction: 'deny',
|
|
424
|
-
* }));
|
|
425
|
-
*
|
|
426
|
-
* @example
|
|
427
|
-
* // Custom handler
|
|
428
|
-
* app.use(botProtection({
|
|
429
|
-
* deny: ['AUTOMATED'],
|
|
430
|
-
* onDetected: (req, res, result) => {
|
|
431
|
-
* console.log(`Bot blocked: ${result.name} (${result.category})`);
|
|
432
|
-
* res.status(403).json({ error: 'Bots not allowed' });
|
|
433
|
-
* },
|
|
434
|
-
* }));
|
|
435
|
-
*/
|
|
436
|
-
declare function botProtection(options?: BotProtectionOptions): RequestHandler;
|
|
437
|
-
|
|
438
|
-
/**
|
|
439
|
-
* @module @arcis/node/middleware/csrf
|
|
440
|
-
* CSRF (Cross-Site Request Forgery) protection middleware
|
|
441
|
-
*
|
|
442
|
-
* Implements the double-submit cookie pattern:
|
|
443
|
-
* 1. Server sets a CSRF token in a cookie
|
|
444
|
-
* 2. Client must send the same token in a header or form field
|
|
445
|
-
* 3. Middleware rejects requests where cookie token !== header/field token
|
|
446
|
-
*
|
|
447
|
-
* This works because an attacker's cross-origin form submission will include
|
|
448
|
-
* the cookie automatically, but cannot read it (same-origin policy) to set
|
|
449
|
-
* the matching header.
|
|
450
|
-
*/
|
|
451
|
-
|
|
452
|
-
/** CSRF protection configuration */
|
|
453
|
-
interface CsrfOptions {
|
|
454
|
-
/** Cookie name for the CSRF token. Default: '_csrf' */
|
|
455
|
-
cookieName?: string;
|
|
456
|
-
/** Header name to check for the token. Default: 'x-csrf-token' */
|
|
457
|
-
headerName?: string;
|
|
458
|
-
/** Form field name to check for the token. Default: '_csrf' */
|
|
459
|
-
fieldName?: string;
|
|
460
|
-
/** Token byte length (hex-encoded = 2x chars). Default: 32 */
|
|
461
|
-
tokenLength?: number;
|
|
462
|
-
/** HTTP methods to protect. Default: ['POST', 'PUT', 'PATCH', 'DELETE'] */
|
|
463
|
-
protectedMethods?: string[];
|
|
464
|
-
/** Paths to exclude from CSRF checks (e.g., webhook endpoints) */
|
|
465
|
-
excludePaths?: string[];
|
|
466
|
-
/** Cookie options */
|
|
467
|
-
cookie?: {
|
|
468
|
-
/** Cookie path. Default: '/' */
|
|
469
|
-
path?: string;
|
|
470
|
-
/** HttpOnly — set false so client JS can read it for headers. Default: false */
|
|
471
|
-
httpOnly?: boolean;
|
|
472
|
-
/** Secure flag (HTTPS only). Default: true in production */
|
|
473
|
-
secure?: boolean;
|
|
474
|
-
/** SameSite attribute. Default: 'Lax' */
|
|
475
|
-
sameSite?: 'Strict' | 'Lax' | 'None';
|
|
476
|
-
/** Cookie domain */
|
|
477
|
-
domain?: string;
|
|
478
|
-
};
|
|
479
|
-
/** Custom error handler when CSRF validation fails */
|
|
480
|
-
onError?: (req: Request, res: Response, next: NextFunction) => void;
|
|
481
|
-
}
|
|
482
|
-
/**
|
|
483
|
-
* Generate a cryptographically random CSRF token.
|
|
484
|
-
*
|
|
485
|
-
* @param length - Byte length (output is hex, so 2x chars). Default: 32
|
|
486
|
-
* @returns Hex-encoded random token
|
|
487
|
-
*
|
|
488
|
-
* @example
|
|
489
|
-
* const token = generateCsrfToken(); // 64 hex chars
|
|
490
|
-
*/
|
|
491
|
-
declare function generateCsrfToken(length?: number): string;
|
|
492
|
-
/**
|
|
493
|
-
* Validate that two CSRF tokens match using constant-time comparison.
|
|
494
|
-
*
|
|
495
|
-
* @param cookieToken - Token from the cookie
|
|
496
|
-
* @param requestToken - Token from the header or form field
|
|
497
|
-
* @returns true if tokens match
|
|
498
|
-
*/
|
|
499
|
-
declare function validateCsrfToken(cookieToken: string, requestToken: string): boolean;
|
|
500
|
-
/**
|
|
501
|
-
* Create CSRF protection middleware using double-submit cookie pattern.
|
|
502
|
-
*
|
|
503
|
-
* For safe methods (GET, HEAD, OPTIONS), sets a CSRF token cookie if not present.
|
|
504
|
-
* For unsafe methods (POST, PUT, PATCH, DELETE), validates the token.
|
|
505
|
-
*
|
|
506
|
-
* @param options - CSRF configuration
|
|
507
|
-
* @returns Express middleware
|
|
508
|
-
*
|
|
509
|
-
* @example
|
|
510
|
-
* // Basic usage
|
|
511
|
-
* app.use(csrfProtection());
|
|
512
|
-
*
|
|
513
|
-
* @example
|
|
514
|
-
* // Exclude webhook paths
|
|
515
|
-
* app.use(csrfProtection({
|
|
516
|
-
* excludePaths: ['/api/webhooks/stripe', '/api/webhooks/github']
|
|
517
|
-
* }));
|
|
518
|
-
*
|
|
519
|
-
* @example
|
|
520
|
-
* // Client-side: read cookie + set header
|
|
521
|
-
* const token = document.cookie.match(/_csrf=([^;]+)/)?.[1];
|
|
522
|
-
* fetch('/api/data', {
|
|
523
|
-
* method: 'POST',
|
|
524
|
-
* headers: { 'X-CSRF-Token': token },
|
|
525
|
-
* credentials: 'same-origin'
|
|
526
|
-
* });
|
|
527
|
-
*/
|
|
528
|
-
declare function csrfProtection(options?: CsrfOptions): RequestHandler;
|
|
529
|
-
/** Alias for csrfProtection */
|
|
530
|
-
declare const createCsrf: typeof csrfProtection;
|
|
531
|
-
|
|
532
|
-
export { validateCsrfToken as A, type BotCategory as B, type CorsOptions as C, type SecureCookieOptions as S, type TokenBucketMiddleware as T, type BotDetectionResult as a, type BotProtectionOptions as b, type CsrfOptions as c, type SlidingWindowMiddleware as d, type SlidingWindowOptions as e, type TokenBucketOptions as f, arcis as g, arcisWithMethods as h, botProtection as i, createCors as j, createCsrf as k, createErrorHandler as l, createHeaders as m, createRateLimiter as n, createSecureCookies as o, createSlidingWindowLimiter as p, createTokenBucketLimiter as q, csrfProtection as r, detectBot as s, enforceSecureCookie as t, errorHandler as u, generateCsrfToken as v, rateLimit as w, safeCors as x, secureCookieDefaults as y, securityHeaders as z };
|
package/dist/index.d.mts
DELETED
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
export { B as BotCategory, a as BotDetectionResult, b as BotProtectionOptions, C as CorsOptions, c as CsrfOptions, S as SecureCookieOptions, d as SlidingWindowMiddleware, e as SlidingWindowOptions, T as TokenBucketMiddleware, f as TokenBucketOptions, g as arcis, h as arcisFunction, i as botProtection, j as createCors, k as createCsrf, l as createErrorHandler, m as createHeaders, n as createRateLimiter, o as createSecureCookies, p as createSlidingWindowLimiter, q as createTokenBucketLimiter, r as csrfProtection, h as default, s as detectBot, t as enforceSecureCookie, u as errorHandler, v as generateCsrfToken, w as rateLimit, x as safeCors, y as secureCookieDefaults, z as securityHeaders, A as validateCsrfToken } from './index-DgJtWMSj.mjs';
|
|
2
|
-
export { P as PiiMatch, K as PiiRedactOptions, L as PiiScanOptions, M as PiiType, c as createSanitizer, d as detectCommandInjection, a as detectHeaderInjection, b as detectJsonpInjection, e as detectNoSqlInjection, f as detectPathTraversal, g as detectPii, h as detectPrototypePollution, i as detectSql, j as detectSsti, k as detectXss, l as detectXxe, m as encodeForAttribute, n as encodeForCss, o as encodeForHtml, p as encodeForJs, q as encodeForUrl, t as isDangerousNoSqlKey, u as isDangerousProtoKey, v as redactObjectPii, w as redactPii, x as sanitizeCommand, y as sanitizeHeaderValue, z as sanitizeHeaders, A as sanitizeJsonpCallback, B as sanitizeObject, C as sanitizePath, D as sanitizeSql, E as sanitizeSsti, F as sanitizeString, G as sanitizeXss, H as sanitizeXxe, I as scanObjectPii, J as scanPii } from './encode-CrQCGlBq.mjs';
|
|
3
|
-
export { E as EmailValidationOptions, a as EmailValidationResult, F as FileInput, V as ValidateFileOptions, b as ValidateFileResult, c as ValidateRedirectOptions, d as ValidateRedirectResult, e as ValidateUrlOptions, f as ValidateUrlResult, g as createValidator, i as isDangerousExtension, h as isRedirectSafe, j as isUrlSafe, k as isValidEmailSyntax, s as sanitizeFilename, v as validate, l as validateEmail, m as validateFile, n as validateRedirect, o as validateUrl, p as verifyEmailMx } from './index-Cd02z-0j.mjs';
|
|
4
|
-
import { IncomingMessage } from 'http';
|
|
5
|
-
export { createRedactor, createSafeLogger, safeLog } from './logging/index.mjs';
|
|
6
|
-
export { MemoryStore, RedisClientLike, RedisStore, RedisStoreOptions, createRedisStore } from './stores/index.mjs';
|
|
7
|
-
export { A as ArcisFunction, a as ArcisMiddleware, b as ArcisOptions, E as ErrorHandlerOptions, F as FieldValidator, H as HeaderOptions, c as HstsOptions, d as HttpError, L as LogOptions, R as RateLimitEntry, e as RateLimitOptions, f as RateLimitResult, g as RateLimitStore, h as RateLimiterMiddleware, S as SafeLogger, i as SanitizeOptions, j as SanitizeResult, T as ThreatInfo, k as ThreatType, V as ValidationConfig, l as ValidationError, m as ValidationResult, n as ValidationSchema } from './types-BOkx5YJc.mjs';
|
|
8
|
-
export { ArcisError, ArcisValidationError, BLOCKED, ERRORS, HEADERS, INPUT, InputTooLargeError, RATE_LIMIT, REDACTION, RateLimitError, SanitizationError, SecurityThreatError, VALIDATION } from './core/index.mjs';
|
|
9
|
-
import 'express';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* @module @arcis/node/utils/duration
|
|
13
|
-
* Parse human-readable duration strings into milliseconds.
|
|
14
|
-
*
|
|
15
|
-
* Supports: ms, s, m, h, d
|
|
16
|
-
*
|
|
17
|
-
* @example
|
|
18
|
-
* parseDuration('5m') // 300000
|
|
19
|
-
* parseDuration('2h') // 7200000
|
|
20
|
-
* parseDuration(60000) // 60000 (passthrough)
|
|
21
|
-
* parseDuration('500ms') // 500
|
|
22
|
-
*/
|
|
23
|
-
/**
|
|
24
|
-
* Parse a duration string or number into milliseconds.
|
|
25
|
-
*
|
|
26
|
-
* @param value - Duration string (e.g. "5m", "2h", "30s") or number (ms)
|
|
27
|
-
* @returns Duration in milliseconds
|
|
28
|
-
* @throws {Error} If the value is not a valid duration
|
|
29
|
-
*
|
|
30
|
-
* @example
|
|
31
|
-
* parseDuration('15m') // 900000
|
|
32
|
-
* parseDuration('1d') // 86400000
|
|
33
|
-
* parseDuration('500ms') // 500
|
|
34
|
-
* parseDuration(60000) // 60000
|
|
35
|
-
*/
|
|
36
|
-
declare function parseDuration(value: string | number): number;
|
|
37
|
-
/**
|
|
38
|
-
* Format milliseconds into a human-readable duration string.
|
|
39
|
-
*
|
|
40
|
-
* @param ms - Duration in milliseconds
|
|
41
|
-
* @returns Human-readable string (e.g. "5m", "2h 30m")
|
|
42
|
-
*/
|
|
43
|
-
declare function formatDuration(ms: number): string;
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* @module @arcis/node/utils/ip
|
|
47
|
-
* Platform-aware client IP detection.
|
|
48
|
-
*
|
|
49
|
-
* Prevents IP spoofing by reading platform-specific headers
|
|
50
|
-
* instead of blindly trusting X-Forwarded-For.
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* // Auto-detect platform from environment
|
|
54
|
-
* const ip = detectClientIp(req);
|
|
55
|
-
*
|
|
56
|
-
* // Explicit platform
|
|
57
|
-
* const ip = detectClientIp(req, { platform: 'cloudflare' });
|
|
58
|
-
*/
|
|
59
|
-
|
|
60
|
-
type Platform = 'auto' | 'cloudflare' | 'vercel' | 'flyio' | 'render' | 'firebase' | 'aws-alb' | 'generic';
|
|
61
|
-
interface DetectIpOptions {
|
|
62
|
-
/** Platform to use for header selection. Default: 'auto' */
|
|
63
|
-
platform?: Platform;
|
|
64
|
-
/** Number of trusted proxies (for X-Forwarded-For parsing). Default: 1 */
|
|
65
|
-
trustedProxyCount?: number;
|
|
66
|
-
}
|
|
67
|
-
interface RequestLike$1 {
|
|
68
|
-
headers: Record<string, string | string[] | undefined>;
|
|
69
|
-
socket?: {
|
|
70
|
-
remoteAddress?: string;
|
|
71
|
-
};
|
|
72
|
-
connection?: {
|
|
73
|
-
remoteAddress?: string;
|
|
74
|
-
};
|
|
75
|
-
ip?: string;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Detect the real client IP address from a request.
|
|
79
|
-
*
|
|
80
|
-
* Uses platform-specific headers when available to prevent IP spoofing.
|
|
81
|
-
* Falls back to X-Forwarded-For (parsed from the right) and then
|
|
82
|
-
* the socket remote address.
|
|
83
|
-
*
|
|
84
|
-
* @param req - HTTP request object (Express, raw http, etc.)
|
|
85
|
-
* @param options - Detection options
|
|
86
|
-
* @returns Client IP address, or 'unknown' if unresolvable
|
|
87
|
-
*
|
|
88
|
-
* @example
|
|
89
|
-
* // Auto-detect platform
|
|
90
|
-
* app.use((req, res, next) => {
|
|
91
|
-
* const clientIp = detectClientIp(req);
|
|
92
|
-
* console.log('Client IP:', clientIp);
|
|
93
|
-
* next();
|
|
94
|
-
* });
|
|
95
|
-
*
|
|
96
|
-
* @example
|
|
97
|
-
* // Behind Cloudflare
|
|
98
|
-
* const ip = detectClientIp(req, { platform: 'cloudflare' });
|
|
99
|
-
*
|
|
100
|
-
* @example
|
|
101
|
-
* // Behind 2 proxies (e.g. CDN + load balancer)
|
|
102
|
-
* const ip = detectClientIp(req, { trustedProxyCount: 2 });
|
|
103
|
-
*/
|
|
104
|
-
declare function detectClientIp(req: RequestLike$1 | IncomingMessage, options?: DetectIpOptions): string;
|
|
105
|
-
/**
|
|
106
|
-
* Check if an IP address is a private/internal address.
|
|
107
|
-
*
|
|
108
|
-
* Detects: loopback, private ranges (RFC 1918), link-local, IPv6 equivalents.
|
|
109
|
-
*/
|
|
110
|
-
declare function isPrivateIp(ip: string): boolean;
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* @module @arcis/node/utils/fingerprint
|
|
114
|
-
* Deterministic request fingerprinting via SHA-256.
|
|
115
|
-
*
|
|
116
|
-
* Generates a stable hash from request characteristics for
|
|
117
|
-
* rate limiting keys, abuse detection, and analytics.
|
|
118
|
-
*
|
|
119
|
-
* @example
|
|
120
|
-
* const fp = await fingerprint(req);
|
|
121
|
-
* // "a3f2b8c1d4e5..."
|
|
122
|
-
*/
|
|
123
|
-
|
|
124
|
-
interface FingerprintOptions {
|
|
125
|
-
/** Include IP address in fingerprint. Default: true */
|
|
126
|
-
ip?: boolean;
|
|
127
|
-
/** Include User-Agent header. Default: true */
|
|
128
|
-
userAgent?: boolean;
|
|
129
|
-
/** Include Accept header. Default: true */
|
|
130
|
-
accept?: boolean;
|
|
131
|
-
/** Include Accept-Language header. Default: true */
|
|
132
|
-
acceptLanguage?: boolean;
|
|
133
|
-
/** Include Accept-Encoding header. Default: true */
|
|
134
|
-
acceptEncoding?: boolean;
|
|
135
|
-
/** Additional custom components to include */
|
|
136
|
-
custom?: string[];
|
|
137
|
-
/** IP detection options */
|
|
138
|
-
ipOptions?: DetectIpOptions;
|
|
139
|
-
}
|
|
140
|
-
interface RequestLike {
|
|
141
|
-
headers: Record<string, string | string[] | undefined>;
|
|
142
|
-
socket?: {
|
|
143
|
-
remoteAddress?: string;
|
|
144
|
-
};
|
|
145
|
-
connection?: {
|
|
146
|
-
remoteAddress?: string;
|
|
147
|
-
};
|
|
148
|
-
ip?: string;
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Generate a deterministic fingerprint for a request.
|
|
152
|
-
*
|
|
153
|
-
* Creates a SHA-256 hash from configurable request components.
|
|
154
|
-
* The fingerprint is stable across requests from the same client
|
|
155
|
-
* (same IP, browser, language settings).
|
|
156
|
-
*
|
|
157
|
-
* @param req - HTTP request object
|
|
158
|
-
* @param options - Fingerprint configuration
|
|
159
|
-
* @returns Hex-encoded SHA-256 hash (64 characters)
|
|
160
|
-
*
|
|
161
|
-
* @example
|
|
162
|
-
* // Default fingerprint (IP + UA + Accept headers)
|
|
163
|
-
* const fp = fingerprint(req);
|
|
164
|
-
*
|
|
165
|
-
* @example
|
|
166
|
-
* // IP-only fingerprint (for simple rate limiting)
|
|
167
|
-
* const fp = fingerprint(req, { userAgent: false, accept: false, acceptLanguage: false, acceptEncoding: false });
|
|
168
|
-
*
|
|
169
|
-
* @example
|
|
170
|
-
* // With custom components
|
|
171
|
-
* const fp = fingerprint(req, { custom: [req.body?.userId] });
|
|
172
|
-
*/
|
|
173
|
-
declare function fingerprint(req: RequestLike, options?: FingerprintOptions): string;
|
|
174
|
-
|
|
175
|
-
export { type DetectIpOptions, type FingerprintOptions, type Platform, detectClientIp, fingerprint, formatDuration, isPrivateIp, parseDuration };
|