const { requireAdminAuth } = require('../../src/middlewares/auth'); const AdminAuthService = require('../../src/services/AdminAuthService'); const AdminUserRepository = require('../../src/repositories/AdminUserRepository'); const dbManager = require('../../src/database/DatabaseManager'); describe('Auth Middleware Unit Test (Session based)', () => { let req, res, next; beforeEach(() => { req = { session: null }; res = { status: jest.fn().mockReturnThis(), json: jest.fn(), locals: {} }; next = jest.fn(); }); test('should reject when no session exists', () => { requireAdminAuth(req, res, next); expect(res.status).toHaveBeenCalledWith(403); expect(res.json).toHaveBeenCalledWith( expect.objectContaining({ error: 'Zugriff verweigert', reason: 'SESSION_REQUIRED' }) ); expect(next).not.toHaveBeenCalled(); }); test('should reject when session user is missing', () => { req.session = {}; requireAdminAuth(req, res, next); expect(res.status).toHaveBeenCalledWith(403); expect(res.json).toHaveBeenCalledWith( expect.objectContaining({ reason: 'SESSION_REQUIRED' }) ); expect(next).not.toHaveBeenCalled(); }); test('should reject non-admin roles', () => { req.session = { user: { id: 1, role: 'viewer' } }; requireAdminAuth(req, res, next); expect(res.status).toHaveBeenCalledWith(403); expect(res.json).toHaveBeenCalledWith( expect.objectContaining({ reason: 'SESSION_REQUIRED' }) ); expect(next).not.toHaveBeenCalled(); }); test('should pass through for admin sessions and expose user on locals', () => { const adminUser = { id: 1, role: 'admin', username: 'testadmin' }; req.session = { user: adminUser }; requireAdminAuth(req, res, next); expect(next).toHaveBeenCalled(); expect(res.status).not.toHaveBeenCalled(); expect(res.locals.adminUser).toEqual(adminUser); }); }); describe('AdminAuthService', () => { beforeEach(async () => { await dbManager.run('DELETE FROM admin_users'); }); afterEach(async () => { await dbManager.run('DELETE FROM admin_users'); }); test('needsInitialSetup reflects admin count', async () => { await expect(AdminAuthService.needsInitialSetup()).resolves.toBe(true); await AdminAuthService.createInitialAdmin({ username: 'existing', password: 'SuperSecure123!' }); await expect(AdminAuthService.needsInitialSetup()).resolves.toBe(false); }); test('createInitialAdmin validates input and detects completed setup', async () => { await expect( AdminAuthService.createInitialAdmin({ username: '', password: 'SuperSecure123!' }) ).rejects.toThrow('USERNAME_REQUIRED'); await expect( AdminAuthService.createInitialAdmin({ username: 'admin', password: 'short' }) ).rejects.toThrow('PASSWORD_TOO_WEAK'); await AdminAuthService.createInitialAdmin({ username: 'seed', password: 'SuperSecure123!' }); await expect( AdminAuthService.createInitialAdmin({ username: 'admin', password: 'SuperSecure123!' }) ).rejects.toThrow('SETUP_ALREADY_COMPLETED'); }); test('createInitialAdmin persists normalized admin when setup allowed', async () => { const result = await AdminAuthService.createInitialAdmin({ username: 'TestAdmin', password: 'SuperSecure123!' }); expect(result.username).toBe('testadmin'); expect(result.role).toBe('admin'); const stored = await AdminUserRepository.getByUsername('testadmin'); expect(stored).toMatchObject({ username: 'testadmin', role: 'admin', is_active: 1 }); }); test('verifyCredentials handles missing users and password mismatches', async () => { await expect(AdminAuthService.verifyCredentials('admin', 'pw')).resolves.toBeNull(); const hash = await AdminAuthService.hashPassword('SuperSecure123!'); await AdminUserRepository.createAdminUser({ username: 'admin', passwordHash: hash, role: 'admin', requiresPasswordChange: false }); await expect(AdminAuthService.verifyCredentials('admin', 'wrong')).resolves.toBeNull(); }); test('verifyCredentials returns sanitized user for valid credentials', async () => { const hash = await AdminAuthService.hashPassword('SuperSecure123!'); await AdminUserRepository.createAdminUser({ username: 'admin', passwordHash: hash, role: 'admin', requiresPasswordChange: true }); const result = await AdminAuthService.verifyCredentials('admin', 'SuperSecure123!'); expect(result).toEqual({ id: expect.any(Number), username: 'admin', role: 'admin', requiresPasswordChange: true }); }); });