import { describe, it, expect, beforeEach } from 'vitest'; import { eq } from 'drizzle-orm'; import { createApp } from '../../src/app'; import { db } from '../../src/db/client'; import { session, user } from '../../src/db/schema'; import { authToken, bearer, resetDb } from '../helpers'; const PASSWORD = 'sterk-wachtwoord-123'; async function signIn(app: ReturnType, email: string) { return app.request('/api/auth/sign-in/email', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ email, password: PASSWORD }), }); } describe('admin user lifecycle (create → sign in → deactivate → reactivate)', () => { beforeEach(resetDb); it('deactivate revokes the live token and blocks sign-in; reactivate restores both', async () => { const app = createApp(); const adminTok = await authToken(app, 'lifecycle-admin@example.com', 'admin'); // admin creates a worker const createRes = await app.request('/api/admin/users', { method: 'POST', headers: bearer(adminTok), body: JSON.stringify({ email: 'lifecycle-worker@example.com', name: 'Lifecycle Worker', password: PASSWORD, role: 'worker', }), }); expect(createRes.status).toBe(200); const created = await createRes.json(); expect(created.status).toBe('active'); // worker signs in → the issued bearer authorizes /api/me const firstSignIn = await signIn(app, 'lifecycle-worker@example.com'); expect(firstSignIn.status).toBe(200); const workerTok = firstSignIn.headers.get('set-auth-token'); if (!workerTok) throw new Error('no worker token'); expect((await app.request('/api/me', { headers: bearer(workerTok) })).status).toBe(200); // admin deactivates the worker const off = await app.request(`/api/admin/users/${created.id}/deactivate`, { method: 'POST', headers: bearer(adminTok), }); expect(off.status).toBe(200); expect((await off.json()).status).toBe('inactive'); // deactivate deleted the session rows → the pre-issued token no longer authorizes /api/me expect(await db.select().from(session).where(eq(session.userId, created.id))).toHaveLength(0); expect((await app.request('/api/me', { headers: bearer(workerTok) })).status).toBe(401); // and a fresh sign-in is blocked while banned expect((await signIn(app, 'lifecycle-worker@example.com')).status).not.toBe(200); // admin reactivates → ban cleared, sign-in works again const on = await app.request(`/api/admin/users/${created.id}/reactivate`, { method: 'POST', headers: bearer(adminTok), }); expect((await on.json()).status).toBe('active'); const [row] = await db.select().from(user).where(eq(user.id, created.id)); expect(row.banned).toBeFalsy(); expect((await signIn(app, 'lifecycle-worker@example.com')).status).toBe(200); }); });