import test from 'node:test'; import assert from 'node:assert/strict'; import { hashPassword, verifyPassword } from '../src/auth.mjs'; import { openDb, createUser, findUserByUsername, listUsers, ensureDefaultAdmin } from '../src/db.mjs'; import { createRouter } from '../src/server/router.mjs'; import { registerAuthRoutes } from '../src/server/routes/auth.mjs'; import { createSession, getSession } from '../src/server/session.mjs'; test('hashPassword/verifyPassword aceita a senha certa e rejeita a errada', () => { const stored = hashPassword('minhaSenha123'); assert.ok(verifyPassword('minhaSenha123', stored)); assert.ok(!verifyPassword('senhaErrada', stored)); }); test('hashPassword gera salt diferente a cada chamada (hashes distintos p/ mesma senha)', () => { assert.notEqual(hashPassword('abc'), hashPassword('abc')); }); test('ensureDefaultAdmin cria admin/admin somente no primeiro acesso', () => { const db = openDb(':memory:'); ensureDefaultAdmin(db); const admin = findUserByUsername(db, 'admin'); assert.ok(admin); assert.equal(admin.role, 'admin'); assert.ok(verifyPassword('admin', admin.password_hash)); createUser(db, { username: 'vendedor1', passwordHash: hashPassword('123456'), role: 'comercial' }); ensureDefaultAdmin(db); // nao deve recriar nem duplicar assert.equal(listUsers(db).length, 2); db.close(); }); test('createUser rejeita username duplicado (constraint UNIQUE)', () => { const db = openDb(':memory:'); createUser(db, { username: 'joao', passwordHash: hashPassword('123456'), role: 'comercial' }); assert.throws(() => createUser(db, { username: 'joao', passwordHash: hashPassword('outra'), role: 'admin' })); db.close(); }); test('usuario autenticado troca a propria senha validando atual e minimo', async () => { const db = openDb(':memory:'); ensureDefaultAdmin(db); const router = createRouter(); registerAuthRoutes(router, { db }); const handler = router.match('PUT', '/api/auth/password').handler; const invoke = async (body) => { let response; await handler({}, {}, { body, user: { id: 1, username: 'admin', role: 'admin' }, json: (status, data) => { response = { status, data }; } }); return response; }; assert.equal((await invoke({ senhaAtual: 'errada', novaSenha: 'novaSenha123' })).status, 403); assert.equal((await invoke({ senhaAtual: 'admin', novaSenha: 'curta' })).status, 400); const token1 = createSession({ id: 1, username: 'admin', role: 'admin' }); const token2 = createSession({ id: 1, username: 'admin', role: 'admin' }); const changed = await invoke({ senhaAtual: 'admin', novaSenha: 'novaSenha123' }); assert.equal(changed.status, 200); assert.equal(changed.data.relogin, true); assert.equal(getSession(token1), null); assert.equal(getSession(token2), null); assert.ok(verifyPassword('novaSenha123', findUserByUsername(db, 'admin').password_hash)); db.close(); }); test('criacao de usuario exige senha com pelo menos 8 caracteres', async () => { const db = openDb(':memory:'); const router = createRouter(); registerAuthRoutes(router, { db }); let response; await router.match('POST', '/api/users').handler({}, {}, { user: { role: 'admin' }, body: { username: 'novo', password: '1234567' }, json: (status, data) => { response = { status, data }; } }); assert.equal(response.status, 400); db.close(); });