Skip to content

Setup & Usage

The Security Module in DomusJS offers secure utilities for hashing passwords and applying rate limiting mechanisms to safeguard your applications.


Register the module in your main bootstrap.ts using the following method:

import { registerSecurityModule, RedisRateLimiter } from '@domusjs/security';
import { Redis } from 'ioredis';
registerSecurityModule({
rateLimiter: new RedisRateLimiter(new Redis({
host: 'localhost',
port: 6379,
password: 'your-redis-password',
})),
});

✅ This registers:

  • Hasher → default BcryptHasher
  • HashingService → wrapper with convenience methods
  • RateLimiter → passed implementation

You may also use the in-memory rate limiter for development:

import { registerSecurityModule, InMemoryRateLimiter } from '@domusjs/security';
registerSecurityModule({
rateLimiter: new InMemoryRateLimiter(),
});

DomusJS provides an Express middleware for applying rate limits using the registered RateLimiter.

import { rateLimitMiddleware } from '@domusjs/security';
app.post('/login', rateLimitMiddleware({
keyResolver: (req) => `login:${req.ip}`,
limit: 5,
windowSec: 60,
}), loginHandler);

✅ Adds headers like X-RateLimit-Remaining and X-RateLimit-Reset
✅ Returns 429 if limit exceeded
✅ You can apply different limits and resolvers per route


You can apply the middleware globally:

app.use(rateLimitMiddleware({
keyResolver: req => req.ip,
}));

And override per route:

app.post('/reset-password',
rateLimitMiddleware({
keyResolver: req => `reset:${req.ip}`,
limit: 3,
windowSec: 300,
}),
resetPasswordHandler
);

💡 This pattern decouples your routes from a shared rate limit bucket, avoiding unintended rate sharing.


import { container } from 'tsyringe';
import { HashingService } from '@domusjs/security';
const hashingService = container.resolve<HashingService>('HashingService');
const hash = await hashingService.hash('my-password');
const isValid = await hashingService.compare('my-password', hash);

✅ Internally uses the Hasher interface, which defaults to BcryptHasher.


interface Hasher {
hash(value: string): Promise<string>;
compare(value: string, hash: string): Promise<boolean>;
}
interface RateLimiter {
consume(key: string, options?: { limit?: number; windowSec?: number }): Promise<{
remaining: number;
resetIn: number;
isLimited: boolean;
}>;
}

✅ You can implement your own logic using memory, Redis, databases, etc.


  • Register the module using registerSecurityModule().
  • Use the provided HashingService for secure password handling.
  • Protect endpoints with rateLimitMiddleware.
  • Customize key resolution and limits per route for granular control.