feat: NextAuth credentials + JWT 8h + rate limiting
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
import { authOptions } from '@/lib/auth'
|
||||
|
||||
// Mock Prisma
|
||||
jest.mock('@/lib/prisma', () => ({
|
||||
prisma: {
|
||||
user: {
|
||||
findUnique: jest.fn(),
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
||||
// Mock rate-limit
|
||||
jest.mock('@/lib/rate-limit', () => ({
|
||||
checkRateLimit: jest.fn(() => true),
|
||||
recordFailedAttempt: jest.fn(),
|
||||
clearAttempts: jest.fn(),
|
||||
}))
|
||||
|
||||
import { prisma } from '@/lib/prisma'
|
||||
import { checkRateLimit, recordFailedAttempt, clearAttempts } from '@/lib/rate-limit'
|
||||
|
||||
const mockFindUnique = prisma.user.findUnique as jest.Mock
|
||||
|
||||
describe('NextAuth authorize', () => {
|
||||
const authorize = (authOptions.providers[0] as any).options.authorize
|
||||
|
||||
beforeEach(() => jest.clearAllMocks())
|
||||
|
||||
it('retourne null si credentials manquants', async () => {
|
||||
const result = await authorize({ email: '', password: '' }, {})
|
||||
expect(result).toBeNull()
|
||||
})
|
||||
|
||||
it('retourne null si utilisateur introuvable', async () => {
|
||||
mockFindUnique.mockResolvedValue(null)
|
||||
const result = await authorize(
|
||||
{ email: 'a@b.com', password: 'wrong' },
|
||||
{ headers: {} }
|
||||
)
|
||||
expect(result).toBeNull()
|
||||
expect(recordFailedAttempt).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('retourne l\'utilisateur si mot de passe correct', async () => {
|
||||
const { hash } = await import('bcryptjs')
|
||||
const hashedPwd = await hash('correct', 12)
|
||||
mockFindUnique.mockResolvedValue({
|
||||
id: 'user1',
|
||||
email: 'a@b.com',
|
||||
name: 'Alice',
|
||||
role: 'gestionnaire',
|
||||
password: hashedPwd,
|
||||
})
|
||||
const result = await authorize(
|
||||
{ email: 'a@b.com', password: 'correct' },
|
||||
{ headers: {} }
|
||||
)
|
||||
expect(result).toEqual({ id: 'user1', email: 'a@b.com', name: 'Alice', role: 'gestionnaire' })
|
||||
expect(clearAttempts).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('lève RATE_LIMITED si bloqué', async () => {
|
||||
;(checkRateLimit as jest.Mock).mockReturnValue(false)
|
||||
await expect(
|
||||
authorize({ email: 'a@b.com', password: 'x' }, { headers: {} })
|
||||
).rejects.toThrow('RATE_LIMITED')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user