import { test } from 'node:test'; import assert from 'node:assert'; import bcrypt from 'bcryptjs'; import jwt from 'jsonwebtoken'; import { pool } from '../db/connection.js'; // Mock the database pool const mockPool = { query: (sql, params) => { if (sql.includes('INSERT INTO users')) { return [{ insertId: 1 }]; } if (sql.includes('SELECT id, email, password_hash FROM users')) { // Simulate a valid user with hashed password const hashedPassword = '$2a$12$O5y0793j8K4h6g7f9e8d7c6b5a4z3y2x1w0v9u8t7s6r5q4p3o2n1m'; return [[{ id: 1, email: 'test@example.com', password_hash: hashedPassword }]]; } return []; } }; // Replace the actual pool with mock const originalPool = pool; pool.query = mockPool.query; // Mock bcrypt.compare to always return true for valid password const originalBcryptCompare = bcrypt.compare; bcrypt.compare = async (password, hash) => { if (password === 'validpassword') { return true; } return false; }; // Mock jwt.sign to return a fixed token const originalJwtSign = jwt.sign; jwt.sign = () => 'mock-jwt-token'; test('login should implement rate limiting for failed attempts', async () => { const req = { body: { email: 'test@example.com', password: 'wrongpassword' } }; const res = { status: (code) => { res.statusCode = code; return res; }, json: (data) => { res.data = data; } }; // First 4 failed attempts should not be rate limited for (let i = 0; i < 4; i++) { await require('../routes/auth').default.post('/login', req, res); assert.strictEqual(res.statusCode, 401); } // 5th attempt should be rate limited await require('../routes/auth').default.post('/login', req, res); assert.strictEqual(res.statusCode, 429); assert.ok(res.data.error.includes('Too many login attempts')); }); test('login should reset rate limit after successful authentication', async () => { const req = { body: { email: 'test@example.com', password: 'validpassword' } }; const res = { status: (code) => { res.statusCode = code; return res; }, json: (data) => { res.data = data; } }; // Successful login should reset the rate limit await require('../routes/auth').default.post('/login', req, res); assert.strictEqual(res.statusCode, 200); // Now try to fail again - should not be rate limited immediately const failedReq = { body: { email: 'test@example.com', password: 'wrongpassword' } }; await require('../routes/auth').default.post('/login', failedReq, res); assert.strictEqual(res.statusCode, 401); }); // Restore the original functions bcrypt.compare = originalBcryptCompare; jwt.sign = originalJwtSign; pool.query = originalPool; export default {};