Which Routes Does the Rate Limiter in lib/auth/rate-limit.ts Cover in DeskcommCRM?
The rate limiter in lib/auth/rate-limit.ts protects five critical authentication endpoints—login, signup, password reset, invitation acceptance, and organization recovery—by enforcing IP-based and identifier-based request limits using distinct bucket keys.
The DeskcommCRM repository implements a centralized authentication rate limiter to prevent brute-force attacks against its Next.js API routes. Located at lib/auth/rate-limit.ts, this utility defines strict request quotas for the most sensitive user-facing operations. Understanding which routes invoke this protection helps developers diagnose 429 errors and tune security policies for the melgarafael/DeskcommCRM codebase.
Authentication Surfaces Protected by the Rate Limiter
The authRateLimited function exported from lib/auth/rate-limit.ts is invoked by five distinct route handlers in app/api/v1/auth/. Each surface uses a unique action key that generates Redis-style bucket identifiers (auth:<action>:ip and auth:<action>:id) to track consumption separately by IP address and hashed user identifier.
Login Endpoint (/api/v1/auth/login)
The login surface enforces dual limits: 60 attempts per IP address and 5 attempts per hashed identifier (email) within a 5-minute window. This protects against both distributed credential stuffing and targeted account cracking.
In app/api/v1/auth/login.ts, the handler invokes:
if (await authRateLimited('login', email, AUTH_LIMITS.login)) {
return fail('RATE_LIMIT_EXCEEDED', 'Muitas tentativas', 429);
}
Signup Endpoint (/api/v1/auth/signup)
New user registration is limited to 20 attempts per IP within a 1-hour window. This prevents automated account creation spam while allowing legitimate user onboarding.
The route handler in app/api/v1/auth/signup.ts uses the action key 'signup' when calling authRateLimited.
Password Reset Endpoint (/api/v1/auth/reset)
Password reset requests are restricted to 30 attempts per IP and 3 attempts per hashed identifier per hour. These tight limits prevent enumeration attacks that probe for registered email addresses.
Implemented in app/api/v1/auth/reset.ts, this route passes 'reset' as the action parameter to the limiter.
Invitation Acceptance Endpoint (/api/v1/auth/invite_accept)
Handling invitation link click-throughs, this surface allows 60 attempts per IP per hour. This accommodates scenarios where multiple users share an IP while still mitigating automated token guessing.
The route file app/api/v1/auth/invite_accept.ts invokes the limiter with the 'invite_accept' action.
Organization Recovery Endpoint (/api/v1/auth/org_recovery)
The first-access recovery flow for organization creation is strictly limited to 5 attempts per IP and 3 attempts per hashed identifier within a 1-hour window. This protects the critical infrastructure provisioning path.
Found in app/api/v1/auth/org_recovery.ts, this handler uses the 'org_recovery' action key.
Rate Limiting Architecture
The core logic resides in lib/auth/rate-limit.ts, which exports the AUTH_LIMITS constant (defined at lines 36‑46) and the authRateLimited helper.
The authRateLimited function signature accepts three parameters:
action: A string key identifying the authentication surface (login,signup,reset,invite_accept, ororg_recovery)identifier: The user's email or ID used to generate the hashed identifier bucket keylimits: The specific quota object fromAUTH_LIMITScontainingmaxIp,maxId, and window durations
When invoked, the function checks consumption against two buckets: auth:<action>:ip for the requesting IP and auth:<action>:id for the hashed user identifier. If either threshold is exceeded, it returns true, prompting the route to return HTTP 429.
Implementation Example
To apply rate limiting in a new authentication route, import the utilities and wrap the handler logic:
import { authRateLimited, AUTH_LIMITS } from '@/lib/auth/rate-limit';
export async function POST(req: Request) {
const { email } = await req.json();
if (await authRateLimited('reset', email, AUTH_LIMITS.reset)) {
return fail('RATE_LIMIT_EXCEEDED', 'Muitas tentativas', 429);
}
// Proceed with authentication logic...
}
This pattern is replicated across all five protected endpoints in the app/api/v1/auth/ directory, ensuring consistent protection against brute-force and enumeration attacks throughout the DeskcommCRM authentication layer.
Summary
- The
lib/auth/rate-limit.tsfile provides centralized rate limiting for DeskcommCRM's authentication system. - Five routes invoke the
authRateLimitedhelper: login, signup, password reset, invitation acceptance, and organization recovery. - Limits combine IP-based tracking (preventing distributed attacks) with identifier-based tracking (preventing targeted account cracking).
- Quotas range from 3 attempts per identifier (strictest for recovery) to 60 attempts per IP (most permissive for login and invites).
- All enforcement happens before credential verification, ensuring failed attempts consume quota and protect database resources.
Frequently Asked Questions
How are rate limit buckets keyed in DeskcommCRM?
Rate limit buckets use composite keys: auth:<action>:ip tracks requests by source IP address, while auth:<action>:id tracks requests by hashed user identifier. This dual-key strategy prevents attackers from bypassing limits by rotating IPs or targeting multiple accounts from the same origin.
What happens when a rate limit is exceeded?
When authRateLimited detects quota exhaustion, it returns true, causing the route handler to immediately return an HTTP 429 response with the message "Muitas tentativas" (Too many attempts). The request never reaches authentication logic or database queries, protecting system resources.
Can the rate limits be customized without modifying source code?
According to the source analysis, limits are hardcoded in the AUTH_LIMITS constant at lines 36‑46 of lib/auth/rate-limit.ts. To adjust thresholds, developers must modify this configuration object and redeploy the application, as there is no external configuration interface implemented in the current version.
Why does the login endpoint have different window durations than other routes?
The login endpoint uses a 5-minute window (60 IP attempts / 5 identifier attempts), whereas signup, reset, invite acceptance, and recovery use 1-hour windows. This shorter window balances security against brute-force attacks with usability, allowing legitimate users who mistype passwords several retry opportunities within minutes rather than forcing hour-long lockouts for simple typos.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →