~/projects/app $
Help me refactor this authentication function to use async/await and add better error handling
I'll help you refactor the authentication function. Let me analyze the current code and improve it with async/await syntax and proper error handling.
Here are the changes I'll make:
- Convert callback-based code to async/await
- Add try/catch blocks for error handling
- Include specific error types for different failure modes
- Add input validation
src/auth/authenticate.js
async function authenticate(credentials) {
const { username, password } = credentials;
// Input validation
if (!username || !password) {
throw new ValidationError('Username and password required');
}
try {
const user = await findUser(username);
if (!user) {
throw new AuthError('User not found');
}
const isValid = await verifyPassword(password, user.hash);
if (!isValid) {
throw new AuthError('Invalid password');
}
return generateToken(user);
} catch (error) {
if (error instanceof AuthError) {
throw error;
}
throw new AuthError('Authentication failed', { cause: error });
}
}
Here's the diff showing what changed:
src/auth/authenticate.js
+18 -12
- function authenticate(credentials, callback) {
+ async function authenticate(credentials) {
const { username, password } = credentials;
- if (!username || !password) {
- return callback(new Error('Missing credentials'));
- }
+ // Input validation
+ if (!username || !password) {
+ throw new ValidationError('Username and password required');
+ }
- findUser(username, (err, user) => {
- if (err) return callback(err);
- if (!user) return callback(new Error('Not found'));
+ try {
+ const user = await findUser(username);
+ if (!user) {
+ throw new AuthError('User not found');
+ }
The refactored code is cleaner and provides better error messages. Want me to also add rate limiting or session management?
~/projects/app $
Yes, add rate limiting please
I'll add rate limiting using a token bucket algorithm. This will prevent brute force attacks by limiting login attempts.
src/auth/rateLimit.js
const rateLimiter = new Map();
export function checkRateLimit(ip, maxAttempts = 5) {
const now = Date.now();
const windowMs = 15 * 60 * 1000; // 15 minutes
const record = rateLimiter.get(ip) || { count: 0, start: now };
if (now - record.start > windowMs) {
record.count = 1;
record.start = now;
} else {
record.count++;
}
rateLimiter.set(ip, record);
return record.count <= maxAttempts;
}
Created src/auth/rateLimit.js
Updated src/auth/authenticate.js