fraud-raksha
v3.1.0
Published
Fraud Raksha is a fast enterprise Node.js fraud detection, risk scoring, bot protection, resilient HTTP, security, and observability SDK.
Downloads
165
Maintainers
Keywords
Readme
🛡️ FRAUD RAKSHA
Fast enterprise fraud detection, risk scoring, security, resilience, and observability for Node.js
Created by Pradeep Kumar Sheoran — Stack Developer
🌐 Official website: https://bsgtechnologies.com
[!IMPORTANT] Fraud Raksha gives an explainable risk decision:
allow,review,challenge, orblock. A risk score helps your application make a safer decision; it is not legal proof that a user committed fraud.
🎓 Learn Here — Start From Zero
New to Node.js security? You are welcome here. Every public function is explained below with:
✅ Simple description · ✅ Syntax · ✅ Parameters · ✅ Return value · ✅ Example and output · ✅ Error handling · ✅ Real use case
Start with 5-Minute Quickstart, then open the Learn Here Lessons.
🔏 Signature v5 Compatibility
Fraud Raksha can decode, decrypt, and verify incoming Signature v5 values. It validates the encrypted envelope, serializer, request IP, and exact user agent. It does not generate Signature v5 values.
| Status | Algorithm | Encryption | Payload format |
| :----: | ---------- | ------------------- | -------------- |
| ✅ | v5_0200H | OpenSSL AES-256-CBC | HTTP query |
| ✅ | v5_0200S | OpenSSL AES-256-CBC | PHP serialize |
| ✅ | v5_0201H | OpenSSL AES-256-GCM | HTTP query |
| ✅ | v5_0201S | OpenSSL AES-256-GCM | PHP serialize |
| ✅ | v5_0101H | sodium secretbox | HTTP query |
| ✅ | v5_0101S | sodium secretbox | PHP serialize |
| ✅ | v5_0200J | OpenSSL AES-256-CBC | JSON |
| ✅ | v5_0201J | OpenSSL AES-256-GCM | JSON |
| ✅ | v5_0101J | sodium secretbox | JSON |
| ✅ | v5_0101M | sodium secretbox | MessagePack |
| ✅ | v5_0200M | OpenSSL AES-256-CBC | MessagePack |
| ✅ | v5_0201M | OpenSSL AES-256-GCM | MessagePack |
Intentionally not supported
| Status | Algorithm | Reason |
| :----: | ---------- | ------------------------- |
| ❌ | v5_0101I | igbinary is not supported |
| ❌ | v5_0200I | igbinary is not supported |
| ❌ | v5_0201I | igbinary is not supported |
Security note: CBC compatibility is provided for legacy signatures, but CBC does not authenticate ciphertext. Prefer GCM or sodium secretbox for new integrations.
✨ What Can You Build?
| Icon | Purpose | What Fraud Raksha Does | Ready | | :--: | -------------------- | --------------------------------------------------------------- | :---: | | 🕵️ | Fraud detection | Explainable fraud signals and risk score | ✅ | | 💳 | Payment protection | Card testing, payment velocity, amount and country checks | ✅ | | 📅 | Booking protection | Booking hoarding and repeated attempt detection | ✅ | | 🔐 | Account protection | Failed login, MFA failure and account takeover signals | ✅ | | 🤖 | Bot protection | Suspicious user-agent and automation detection | ✅ | | 📱 | Device intelligence | Fingerprint, emulator, rooted device and multi-account signals | ✅ | | 🌍 | IP intelligence | Adapter support for VPN, proxy, Tor, hosting and abuse score | ✅ | | 🚦 | Distributed velocity | Atomic in-memory or Redis counters | ✅ | | 🧩 | Rules engine | Safe JSON rules without arbitrary JavaScript execution | ✅ | | 🧠 | ML integration | Plug in an internal or vendor risk model | ✅ | | 🧪 | Shadow testing | Test policies without blocking real users | ✅ | | 🗂️ | Analyst review | Audit sinks, signed webhooks and case-management adapter | ✅ | | 🌐 | Secure HTTP | Retry, circuit breaker, rate limits, SSRF and TLS controls | ✅ | | 📊 | Monitoring | Metrics, Prometheus output and OpenTelemetry bridge | ✅ | | 🩺 | Health checks | Database, external service, memory and CPU/load checks | ✅ | | ⚡ | Performance | LRU cache, memoization, async pool and token bucket | ✅ | | 🔏 | Privacy | Redaction, HMAC identifiers, retention and erasure | ✅ | | 🔏 | Signature v5 | CBC, GCM and secretbox verification across four payload formats | ✅ |
📚 Table of Contents
- Why Fraud Raksha
- Signature v5 Compatibility
- Installation
- 5-Minute Quickstart
- How a Decision Works
- Which Function Should I Use?
- Learn Here Lessons
- Performance Graph
- Security Checklist
- Quality and Verification
- FAQ
- Author and Signature
- License
💚 Why Fraud Raksha?
- Easy for freshers: copyable TypeScript examples and predictable outputs.
- Useful for enterprises: distributed state, tenant policies, audit trails and adapters.
- Explainable: every decision contains score, action, confidence and signals.
- Dependency-light: Redis, OpenTelemetry, intelligence and ML are optional adapters.
- Dual package: ESM and CommonJS exports with strict TypeScript declarations.
- Fast: every minified JavaScript entry is protected by a 50 KB release gate.
- Secure by design: secret redaction, HMAC identifiers, SSRF controls and signed webhooks.
📦 Installation
npm install fraud-rakshaRequirements:
| Requirement | Value |
| --------------- | ------------------------ |
| Node.js | >=20 |
| Package manager | npm |
| Module systems | ESM and CommonJS |
| Language | JavaScript or TypeScript |
🚀 5-Minute Quickstart
ESM / TypeScript
import { DefaultEnterpriseFraudEngine } from 'fraud-raksha/fraud';
const engine = new DefaultEnterpriseFraudEngine({
policy: {
id: 'login-risk',
version: '1.0.0',
tenantId: 'my-app',
thresholds: { review: 30, challenge: 55, block: 80 },
challengeType: 'otp'
}
});
const decision = await engine.evaluate({
tenantId: 'my-app',
eventType: 'auth.login',
userId: 'user-101',
ip: '203.0.113.10',
failedLoginCount: 6
});
console.log(decision.action, decision.score);Output:
review 30CommonJS
const { FraudDetector } = require('fraud-raksha/fraud');
const fraud = new FraudDetector();
const decision = fraud.evaluate({ failedLoginCount: 6 });
console.log(decision.action);Output:
review🔄 How a Decision Works
Request / Login / Booking / Payment
│
▼
Tenant Policy + Velocity
│
▼
Device + IP + Behavior Rules
│
▼
Optional ML Risk Model
│
▼
Score + Explainable Signals
│
┌─────────┼──────────┐
▼ ▼ ▼
ALLOW CHALLENGE REVIEW / BLOCKExample decision:
{
"decisionId": "risk-01J...",
"action": "challenge",
"score": 65,
"confidence": 0.85,
"policyVersion": "[email protected]",
"signals": [
{ "ruleId": "payment_velocity", "score": 35, "severity": "high" },
{ "ruleId": "unknown_device", "score": 15, "severity": "low" }
],
"challenge": { "type": "otp" }
}🧭 Which Function Should I Use?
| Your task | Use this API |
| -------------------------------- | ----------------------------------------- |
| Enterprise fraud decision | DefaultEnterpriseFraudEngine.evaluate() |
| Small single-process fraud check | FraudDetector.evaluate() |
| Historical policy test | engine.simulate() |
| Device identity hash | createDeviceFingerprint() |
| Distributed velocity | RedisFraudStore |
| Safe configurable rule | evaluateRuleDefinition() |
| Express/NestJS integration | createFraudMiddleware() |
| Fastify integration | createFastifyFraudHook() |
| Safe structured logs | Logger |
| Reliable outbound request | HttpClient |
| Input validation | ValidatorService.validate() |
| Environment validation | ConfigLoader |
| Prometheus endpoint body | toPrometheus() |
| Database/service health | HealthCheckService |
| Remove secrets from objects | redact() |
| Privacy-safe identifier | PrivacyProtector.hash() |
| Signed event delivery | SignedWebhookPublisher.publish() |
| Cache repeated reads | LruCache or memoize() |
| Limit concurrent promises | asyncPool() |
| Stable signature JSON | stableStringify() |
| Decode an incoming v5 signature | decodeSignatureV5() |
| Verify v5 request binding | verifySignatureV5() |
🎓 Learn Here Lessons
1. Enterprise Fraud Engine
createEnterpriseFraudEngine() / new DefaultEnterpriseFraudEngine()
Description: Creates the full async engine for multi-server fraud decisions.
Syntax:
const engine = createEnterpriseFraudEngine(options);
// or
const engine = new DefaultEnterpriseFraudEngine(options);| Parameter | Type | Required | Easy meaning |
| ---------------------------- | ---------------------------- | :------: | ----------------------------------- |
| options.store | FraudStore | ❌ | Counter storage; defaults to memory |
| options.policy | FraudPolicy | ❌ | One fixed policy |
| options.policyProvider | FraudPolicyProvider | ❌ | Loads policy by tenant and event |
| options.ipIntelligence | IpIntelligenceProvider | ❌ | Looks up VPN, Tor and IP risk |
| options.deviceIntelligence | DeviceIntelligenceProvider | ❌ | Looks up device risk |
| options.riskModel | RiskModel | ❌ | Adds an ML/vendor score |
| options.auditSinks | FraudAuditSink[] | ❌ | Receives audit events |
| options.caseManagement | CaseManagementAdapter | ❌ | Creates review cases |
| options.hashIdentifier | (value) => string | ⭐ | Protects IDs in counters and audits |
Returns: A DefaultEnterpriseFraudEngine.
Errors: Policy/store/provider errors reject the Promise. Wrap high-risk operations in try/catch and choose your fail-open/fail-closed policy.
Use cases: distributed login security, payment fraud, booking abuse, account takeover.
engine.evaluate()
const decision = await engine.evaluate(event, {
mode: 'enforce',
emitAudit: true,
createCase: true
});| Parameter | Type | Required | Meaning |
| -------------------- | ----------------------- | :------: | ---------------------------------------- |
| event | FraudEvent | ✅ | Login, request, booking or payment facts |
| options.mode | 'enforce' \| 'shadow' | ❌ | Enforce or only observe |
| options.emitAudit | boolean | ❌ | Send decision to audit sinks |
| options.createCase | boolean | ❌ | Open analyst review case |
Returns: Promise<FraudDecision>.
Output:
action=challenge score=65 [email protected]Error handling:
try {
const decision = await engine.evaluate(event);
} catch (error) {
logger.error('Risk engine unavailable', {}, error as Error);
// Choose manual review or fail closed for high-value payments.
}engine.simulate()
Description: Runs historical events in shadow mode without audit/case side effects.
const report = await engine.simulate(events);
console.log(report.summary);Returns:
{ allow: 80, review: 12, challenge: 6, block: 2 }Errors: Rejects if a policy, store, or external provider fails.
Use case: measure false positives before activating a rule.
engine.reset()
await engine.reset();Returns: Promise<void>.
Use case: tests and controlled cache resets. Avoid resetting production Redis counters during live traffic.
2. Simple Fraud Detector
createFraudDetector() / new FraudDetector()
Description: Creates a synchronous, single-process detector.
const fraud = createFraudDetector({
reviewThreshold: 30,
blockedCountries: ['NK']
});Returns: FraudDetector.
Errors: Constructor does not perform network operations.
Use case: CLI tools, one Node process, local pre-checks and tests.
fraud.evaluate()
const result = fraud.evaluate({
email: '[email protected]',
userAgent: 'curl/8',
failedLoginCount: 6
});| Parameter | Type | Required | Meaning |
| --------- | ------------ | :------: | ---------------------------------------- |
| event | FraudEvent | ✅ | Facts you already know about the request |
Returns: FraudDecision immediately, not a Promise.
action=challenge signals=failed_login_velocity,suspicious_user_agent,disposable_emailfraud.reset()
Clears local IP/user/session counters.
fraud.reset();Returns: void.
Use case: test isolation or a deliberate local reset.
3. Device Fingerprint
createDeviceFingerprint()
Description: Creates a normalized HMAC device identifier. It does not collect browser data itself.
const fingerprint = createDeviceFingerprint(
{
userAgent: request.headers['user-agent'],
platform: 'windows',
timezone: 'Asia/Calcutta'
},
process.env.DEVICE_HMAC_SECRET!
);| Parameter | Type | Required | Meaning |
| --------- | ------------------------ | :------: | ------------------------------------------ |
| input | DeviceFingerprintInput | ✅ | Stable device/browser signals |
| secret | string | ✅ | Private HMAC secret, minimum 16 characters |
Returns: A string beginning with dfp:.
dfp:uRmQ...privacy-safe-hashErrors: Throws when the secret has fewer than 16 characters.
Use case: detect one device creating many accounts without storing raw device attributes.
4. Fraud Stores
new InMemoryFraudStore()
const store = new InMemoryFraudStore({ maxKeys: 100_000 });
const count = await store.increment('tenant:login:ip:hash', 60_000);| Method | Parameters | Return | Use |
| ------------- | ----------------- | ----------------- | ------------------------ |
| increment() | key, windowMs | Promise<number> | Atomic-style local count |
| reset() | optional key | Promise<void> | Clear one/all counters |
Errors: No external service errors; memory is bounded by maxKeys.
new RedisFraudStore()
const store = new RedisFraudStore({
client: redis,
keyPrefix: 'production:risk:'
});| Parameter | Type | Required | Meaning |
| ----------- | ------------------ | :------: | ----------------------------------------------------- |
| client | RedisFraudClient | ✅ | Object with incr, pExpire, del, optional scan |
| keyPrefix | string | ❌ | Namespace for keys |
Returns: A FraudStore.
Errors: Redis errors reject; resetting every key also requires scan().
Use case: correct velocity counts across many Node.js servers.
new VelocityStore()
Legacy synchronous local counter:
const velocity = new VelocityStore({ windowMs: 60_000 });
console.log(velocity.increment('ip:hash')); // 1
velocity.clear();5. JSON Rules
evaluateRuleDefinition()
Description: Evaluates a safe data rule. No eval() and no arbitrary JavaScript.
const signal = evaluateRuleDefinition(
{
id: 'large_payment',
message: 'Large payment requires review',
score: 40,
severity: 'high',
all: [{ field: 'transaction.amount', operator: 'gte', value: 50000 }]
},
event
);| Parameter | Type | Required |
| --------- | --------------------- | :------: |
| rule | FraudRuleDefinition | ✅ |
| event | FraudEvent | ✅ |
Returns: FraudSignal | undefined.
{ ruleId: "large_payment", score: 40, severity: "high" }Errors: Invalid regular expressions used by matches can throw. Validate admin-authored rules before activation.
Use case: update risk policy from a database without redeploying application code.
6. Policy, Audit and Retention
new InMemoryFraudPolicyProvider()
const policies = new InMemoryFraudPolicyProvider();
policies.set(policy, 'payment.create');
const selected = await policies.getPolicy('tenant-a', 'payment.create');| Method | Return | Error |
| -------------------------------- | ---------------------- | ---------------------------- |
| set(policy, eventType?) | void | None |
| getPolicy(tenantId, eventType) | Promise<FraudPolicy> | Throws when no policy exists |
new WebhookFraudAuditSink()
const sink = new WebhookFraudAuditSink(publisher);
await sink.publish({ decision, event });Returns: Promise<void>.
Errors: Propagates webhook delivery errors. The enterprise engine isolates sink failures from the user decision.
Use case: SIEM, Kafka gateway, audit service or review dashboard.
new FraudRetentionManager()
const retention = new FraudRetentionManager({
repository,
retentionDays: 90,
hashSubject: (id) => privacy.hash(id)
});
await retention.purgeExpired();
await retention.eraseSubject('user-101');| Method | Return | Meaning |
| ------------------ | ----------------- | ---------------------------- |
| purgeExpired() | Promise<number> | Deleted old records |
| eraseSubject(id) | Promise<number> | Deleted one person's records |
Errors: Invalid retention days throw; repository failures reject.
7. Logger
new Logger()
const logger = new Logger({
serviceName: 'booking-api',
level: 'info',
correlationId: 'req-101'
});| Parameter | Type | Default |
| -------------- | ----------------------------------------- | ---------------------- |
| serviceName | string | Required |
| level | error \| warn \| info \| debug \| trace | info |
| format | json \| pretty | JSON in production |
| redact | boolean \| RedactionOptions | Enabled |
| includeStack | boolean | Disabled in production |
Methods:
logger.error('Payment failed', { cardNumber: '4111...' }, error);
logger.warn('High retry count');
logger.info('Booking created', { bookingId: 'B-101' });
logger.debug('Rule details', { score: 40 });
logger.trace('Very detailed event');
logger.setCorrelationId('req-102');
const child = logger.child({ correlationId: 'job-1' });Output:
{
"level": "info",
"serviceName": "booking-api",
"correlationId": "req-101",
"message": "Booking created"
}Returns: Log methods return void; child() returns a new Logger.
Error handling: Sink failures are controlled by your custom sink. Sensitive keys are redacted automatically.
8. HTTP Client
new HttpClient()
const http = new HttpClient({
baseURL: 'https://api.example.com',
timeoutMs: 5000,
retry: { retries: 3, baseDelayMs: 100 },
circuitBreaker: { failureThreshold: 5 },
rateLimit: { maxRequests: 100, windowMs: 60_000 },
security: {
allowedHosts: ['api.example.com'],
blockPrivateNetworks: true,
maxResponseBytes: 2_000_000
}
});| Method | Parameters | Return |
| -------------- | -------------------------- | --------------------------- |
| request<T>() | Axios request config | Promise<AxiosResponse<T>> |
| get<T>() | URL, optional config | Promise<AxiosResponse<T>> |
| post<T>() | URL, data, optional config | Promise<AxiosResponse<T>> |
Example:
try {
const response = await http.get<{ id: string }>('/users/101');
console.log(response.status, response.data.id);
} catch (error) {
console.error(serializeError(error));
}200 101Errors: Axios network errors, RateLimitError, open circuit errors, SSRF policy errors and TLS errors.
Use case: reliable calls to payment, identity and notification services.
new RetryStrategy() / sleep()
const retry = new RetryStrategy({ retries: 3, baseDelayMs: 100 });
console.log(retry.evaluate(1, 503)); // { shouldRetry: true, delayMs: 100 }
await sleep(100);new CircuitBreaker()
const breaker = new CircuitBreaker({ failureThreshold: 5 });
const value = await breaker.execute(() => callService());
console.log(breaker.state); // closed | open | half-open9. Errors
Error classes
throw new ValidationError('Email is invalid', { field: 'email' });
throw new NotFoundError('Booking not found');
throw new UnauthorizedError();
throw new ForbiddenError();
throw new ConflictError('Booking already exists');
throw new RateLimitError();
throw new ExternalServiceError('Payment service unavailable');All classes extend AppError.
| Property | Meaning |
| --------------- | ---------------------------- |
| statusCode | HTTP response status |
| errorCode | Stable machine-readable code |
| context | Safe debugging details |
| isOperational | Expected application error |
serializeError()
const body = serializeError(error, {
includeStack: process.env.NODE_ENV !== 'production'
});Returns: A consistent safe error object. Unknown errors become Internal server error.
Use case: API error responses without production stack leakage.
10. Validator and Config
ValidatorService.validate() / safeValidate()
const validator = new ValidatorService();
const schema = z.object({ email: z.string().email() });
const data = validator.validate(schema, { email: '[email protected]' });
const result = validator.safeValidate(schema, input);| Method | Return | Error |
| ---------------- | ----------------- | -------------------------------- |
| validate() | Parsed typed data | Throws ValidationError |
| safeValidate() | Zod safe result | Does not throw for invalid input |
new ConfigLoader()
const config = new ConfigLoader({
schema: baseConfigSchema,
loadEnvFile: true
});
console.log(config.get('SERVICE_NAME'));
console.log(config.all());Returns: Validated configuration.
Errors: Throws a validation error when required environment values are invalid.
nestedEnv()
const nested = nestedEnv('APP');
// APP__DATABASE__HOST becomes { DATABASE: { HOST: "..." } }Returns: A nested object.
Use case: turn double-underscore environment variables into structured config.
11. Metrics and Tracing
MetricsService
const metrics = new MetricsService();
metrics.incrementCounter('requests_total', { route: '/login' });
metrics.recordHistogram('request_duration_ms', 12.5, { route: '/login' });
console.log(metrics.snapshot());
metrics.reset();| Method | Return |
| -------------------- | ----------------------- |
| incrementCounter() | void |
| recordHistogram() | void |
| snapshot() | Counters and histograms |
| reset() | void |
toPrometheus()
const body = toPrometheus(metrics);
response.setHeader('content-type', 'text/plain');
response.end(body);Output:
# TYPE requests_total counter
requests_total{route="/login"} 1new TelemetryBridge()
const telemetry = new TelemetryBridge(tracer);
await telemetry.trace('fraud.evaluate', async (span) => {
const decision = await engine.evaluate(event);
telemetry.recordFraudDecision(span, decision);
return decision;
});Returns: The operation result.
Errors: Records the exception, ends the span and rethrows.
12. Health and Middleware
HealthCheckService
const health = new HealthCheckService();
health.registerDatabaseCheck('postgres', () => db.query('select 1'));
health.registerExternalServiceCheck('payments', () => http.get('/health'));
health.registerSystemCheck();
const result = await health.run();
console.log(result.status);healthyMethods register(), registerDatabaseCheck(), registerExternalServiceCheck() and registerSystemCheck() return void. run() returns the aggregate health report.
securityHeaders()
for (const [name, value] of Object.entries(securityHeaders())) {
response.setHeader(name, value);
}Returns: A security header record.
createFraudMiddleware()
Works with Express and NestJS middleware:
app.use(
createFraudMiddleware({
engine,
eventFactory: (request) => ({
tenantId: 'my-app',
eventType: `${request.method}:${request.url}`,
ip: request.ip
})
})
);Returns: An async middleware function.
Errors: Calls next(error). Block/challenge responses include only safe decision fields by default.
createFastifyFraudHook()
fastify.addHook('preHandler', createFastifyFraudHook({ engine, eventFactory }));Returns: A Fastify pre-handler.
13. Security Utilities
redact()
console.log(redact({ email: '[email protected]', password: 'secret' }));{ email: "[email protected]", password: "[REDACTED]" }Errors: Circular objects and excess depth are replaced safely.
Use case: logs, audit events and support diagnostics.
new PrivacyProtector()
const privacy = new PrivacyProtector(process.env.HMAC_SECRET!);
const digest = privacy.hash('[email protected]');
console.log(privacy.verify('[email protected]', digest)); // true| Method | Return |
| ----------------------- | ---------------------- |
| hash(value) | Stable HMAC identifier |
| verify(value, digest) | boolean |
Errors: Secret shorter than 16 characters throws.
sanitizeObjectKey()
sanitizeObjectKey(userKey);Returns: The safe key.
Errors: Throws for __proto__, prototype, or constructor.
Use case: prototype-pollution protection.
assertSafeOutboundUrl() / isPrivateAddress()
await assertSafeOutboundUrl(url, {
allowedHosts: ['api.example.com'],
blockPrivateNetworks: true
});
console.log(isPrivateAddress('127.0.0.1')); // trueErrors: Rejects unsupported protocols, credentials, disallowed hosts and private destinations.
createSecureHttpsAgent()
const agent = createSecureHttpsAgent({
minVersion: 'TLSv1.3',
cert: clientCertificate,
key: clientKey,
certificatePins: ['sha256/base64-pin']
});Returns: Node https.Agent | undefined.
Use case: mTLS and certificate pinning.
SignedWebhookPublisher.publish() / verifyWebhookSignature()
const publisher = new SignedWebhookPublisher({
url: 'https://audit.example.com/events',
secret: process.env.WEBHOOK_SECRET!
});
await publisher.publish({ decisionId: 'risk-101' });Receiver:
const valid = verifyWebhookSignature({
body: rawBody,
timestamp: request.headers['x-fraud-raksha-timestamp'],
signature: request.headers['x-fraud-raksha-signature'],
secret: process.env.WEBHOOK_SECRET!
});Returns: publish() returns Promise<void>; verification returns boolean.
Errors: Delivery rejects for non-2xx responses or timeout.
14. Performance Utilities
new LruCache()
const cache = new LruCache({ maxSize: 1000, ttlMs: 60_000 });
cache.set('user:1', { id: 1 });
console.log(cache.get('user:1')); // { id: 1 }
cache.delete('user:1');
cache.clear();Methods: get, set, has, delete, clear, size.
memoize()
const total = memoize((a: number, b: number) => a + b);
console.log(total(2, 3)); // 5
console.log(total(2, 3)); // 5 from cacheReturns: A cached version of the function.
Use case: repeated deterministic work.
asyncPool()
const results = await asyncPool(ids, (id) => loadUser(id), { concurrency: 5 });| Parameter | Meaning |
| ------------- | --------------------------- |
| items | Input list |
| worker | Async function for one item |
| concurrency | Maximum simultaneous work |
Returns: Ordered result array.
Errors: Rejects when a worker rejects.
new TokenBucket()
const limiter = new TokenBucket({
capacity: 100,
refillTokens: 100,
refillIntervalMs: 60_000
});
console.log(limiter.tryRemove(1)); // true
console.log(limiter.available); // 99Use case: smooth local rate limiting.
benchmark()
const result = benchmark('parse', 100_000, () => JSON.parse('{"ok":true}'));
console.log(result.opsPerSecond);Returns: { name, iterations, totalMs, opsPerSecond }.
Errors: The tested function's error is propagated.
15. Serializer Utilities
stableStringify()
console.log(stableStringify({ b: 2, a: 1 }));{"a":1,"b":2}Use case: signatures, cache keys and repeatable audit payloads.
Base64URL functions
const encoded = encodeBase64Url('hello');
const bytes = decodeBase64Url(encoded);
const text = decodeBase64UrlToString(encoded);| Function | Return |
| -------------------------------- | --------------- |
| encodeBase64Url(value) | URL-safe string |
| decodeBase64Url(value) | Buffer |
| decodeBase64UrlToString(value) | UTF-8 string |
Query-string functions
const query = toQueryString({ page: 1, tags: ['node', 'security'] });
const parsed = parseQueryString(query);Returns: Query string or parsed key/value object.
Object functions
const publicUser = pick(user, ['id', 'name']);
const withoutPassword = omit(user, ['password']);
const frozen = deepFreeze(config);| Function | Meaning | Return |
| -------------- | -------------------- | --------------------- |
| pick() | Keep selected keys | New object |
| omit() | Remove selected keys | New object |
| deepFreeze() | Recursively freeze | Frozen original value |
16. Signature v5
decodeSignatureV5()
Description: Decrypts an incoming Signature v5 envelope and safely converts its HTTP query, PHP serialize, JSON, or MessagePack payload into a JavaScript object.
Syntax:
const decoded = await decodeSignatureV5(signature, key, options);| Parameter | Type | Required | Easy meaning |
| --------------------------- | ------------------------------------- | :------: | ----------------------------------- |
| signature | string \| Buffer | ✅ | Base64URL signature or raw envelope |
| key | Buffer \| string \| (zoneId) => key | ✅ | Exact 32-byte decryption key |
| options.maxSignatureBytes | number | ❌ | Maximum accepted envelope size |
Example:
import { decodeSignatureV5 } from 'fraud-raksha/signature-v5';
const decoded = await decodeSignatureV5(
request.headers['x-signature-v5'] as string,
async (zoneId) => secretStore.getSignatureKey(zoneId)
);
console.log(decoded.algorithm, decoded.zoneId, decoded.payload);Output:
v5_0201J 42n { "b.ua": "Mozilla/5.0", "result": { "score": 12 } }Returns: Promise<DecodedSignatureV5> with version, zone ID, algorithm, encryption, serializer, and payload.
Errors: Throws SignatureV5Error for malformed Base64URL, wrong version, invalid key, truncated data, failed authentication/decryption, unsupported serializer, or unsafe payload keys.
Use case: Read trusted fraud or ad-verification data before connecting it to the current HTTP request.
verifySignatureV5()
Description: Decodes the signature and also checks that its signed IP prefix and exact b.ua value match the current request.
Syntax:
const verified = await verifySignatureV5({
signature,
key,
ipAddresses,
userAgent
});| Parameter | Type | Required | Easy meaning |
| ------------------- | -------------------------------------------- | :------: | ------------------------------------ |
| signature | string \| Buffer | ✅ | Incoming Signature v5 |
| key | Buffer \| string \| SignatureV5KeyResolver | ✅ | 32-byte key or zone-aware key loader |
| ipAddresses | string[] | ✅ | Trusted request IP candidates |
| userAgent | string | ✅ | Current request user-agent |
| maxSignatureBytes | number | ❌ | Envelope size safety limit |
import { verifySignatureV5 } from 'fraud-raksha/signature-v5';
const verified = await verifySignatureV5({
signature: req.headers['x-signature-v5'] as string,
key: process.env.SIGNATURE_V5_KEY!,
ipAddresses: [req.ip],
userAgent: req.headers['user-agent'] ?? ''
});
console.log(verified.verified, verified.matchingIp, verified.result);true 203.0.113.24 { "score": 12 }Returns: Promise<VerifiedSignatureV5> with verified: true, the matching IP, and signed result.
Errors: IP_MISMATCH or USER_AGENT_MISMATCH is returned when request binding fails; decryption and payload failures use stable error codes on SignatureV5Error.code.
Use case: Accept a Signature v5 result only for the browser/request that originally produced it.
isSupportedSignatureV5Algorithm()
Description: Checks an algorithm name before processing it.
console.log(isSupportedSignatureV5Algorithm('v5_0201J')); // true
console.log(isSupportedSignatureV5Algorithm('v5_0201I')); // false| Parameter | Type | Return |
| ----------- | -------- | ------------------- |
| algorithm | string | Type-safe boolean |
Errors: Never throws.
Use case: Validate configuration and show a clear compatibility message before decoding.
📈 Verified Performance Graph
Local Node.js benchmark, 100,000 iterations. Performance varies by hardware; run npm run bench on your own server.
| Operation | Visual throughput | Verified ops/sec | | ------------------ | ---------------------------------------- | ---------------: | | LRU set/get | 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 | 6,584,926 | | Memoized math | 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 | 4,716,380 | | Query-string build | 🟩🟩🟩🟩🟩🟩 | 1,941,242 | | Base64URL | 🟩🟩🟩🟩🟩 | 1,759,461 | | Stable stringify | 🟩🟩 | 645,369 |
Bundle gate:
| Entry | ESM minified | CJS minified | Limit | | ---------------- | -----------: | -----------: | -------------: | | Root package | 43.42 KB | 44.07 KB | ✅ Under 50 KB | | Fraud subpath | 18.12 KB | 18.19 KB | ✅ Under 50 KB | | Security subpath | 3.55 KB | 3.72 KB | ✅ Under 50 KB | | Signature v5 | 6.62 KB | 6.66 KB | ✅ Under 50 KB |
🔐 Security Checklist
- ✅ Keep HMAC, webhook, TLS and vendor secrets in a secret manager.
- ✅ Hash user IDs, IPs, emails, sessions and device IDs before persistent storage.
- ✅ Never send full card numbers, CVV, passwords or access tokens in a fraud event.
- ✅ Validate admin-authored JSON rules before activation.
- ✅ Test new rules in shadow mode.
- ✅ Keep policy versions immutable for reproducible audits.
- ✅ Define audit retention by region and regulation.
- ✅ Use Redis for distributed production velocity.
- ✅ Use human review for ambiguous high-impact decisions.
- ✅ Run
npm audit,npm run verify, andnpm run pack:drybefore publishing.
✅ Quality and Verification
| Check | Result | | ------------------- | :-----------: | | Strict TypeScript | ✅ Passed | | ESLint | ✅ Passed | | Test files | ✅ 14 passed | | Tests | ✅ 82 passed | | Statement coverage | ✅ 94.72% | | Line coverage | ✅ 95.44% | | Branch coverage | ✅ 85.17% | | Dependency audit | ✅ 0 findings | | ESM consumer | ✅ Passed | | CommonJS consumer | ✅ Passed | | Node versions in CI | ✅ 20, 22, 24 | | SBOM | ✅ CycloneDX | | npm provenance | ✅ Enabled |
❓ FAQ
No. It produces explainable risk evidence and a recommended application action. Combine it with verified intelligence, business rules and human review.
No for learning, tests and one Node process. Yes for reliable shared velocity across multiple production servers.
No. Implement the provided adapter interfaces with your approved vendor. This keeps credentials, cost and data residency under your control.
Yes. Fraud Raksha ships both ESM and CommonJS JavaScript plus TypeScript declarations.
“Raksha” means protection. Fraud Raksha is designed as a protective decision layer around logins, bookings, payments and APIs.
👨💻 Author and Signature
| Field | Details |
| ---------------- | -------------------------------------------------------------- |
| Author | Pradeep Kumar Sheoran |
| Role | Stack Developer |
| Website | https://bsgtechnologies.com |
| Package | fraud-raksha |
| Signature export | FRAUD_RAKSHA_INFO |
import { FRAUD_RAKSHA_INFO } from 'fraud-raksha';
console.log(FRAUD_RAKSHA_INFO.signature);
// Created by Pradeep Kumar Sheoran (Stack Developer)The same attribution is included as a standard comment banner in generated ESM and CommonJS files. It does not alter logs, decisions, requests or user data.
🧰 Commands
| Command | Purpose |
| ----------------------- | ------------------------------------------- |
| npm run verify | Typecheck, lint, tests, build and size gate |
| npm test | Run coverage tests |
| npm run bench | Run local performance graph data |
| npm run audit:runtime | Audit runtime dependencies |
| npm run sbom | Generate CycloneDX SBOM |
| npm run pack:dry | Inspect npm publish payload |
🤝 Contributing
- Create a feature branch.
- Add tests for behavior changes.
- Add or update the matching Learn Here lesson.
- Run
npm run verify. - Inspect
npm run pack:dry.
📄 License
MIT © Pradeep Kumar Sheoran.
🛡️ Fraud Raksha
Protection that explains its decisions.
Website · npm Package · Back to Top
Pradeep Kumar Sheoran — Stack Developer
