import { test } from 'node:test'; import assert from 'node:assert/strict'; import { spawn } from 'node:child_process'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; const root = path.join(path.dirname(fileURLToPath(import.meta.url)), '..'); test('iam login, permission check, user CRUD', async () => { const port = 18028; const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'iam-')); const child = spawn(process.execPath, ['src/server.js'], { cwd: root, env: { ...process.env, PORT: String(port), STAFF_IAM_PATH: path.join(dir, 'iam.json') }, stdio: ['ignore', 'pipe', 'pipe'], }); await new Promise((r) => setTimeout(r, 500)); try { const h = await (await fetch(`http://127.0.0.1:${port}/health`)).json(); assert.equal(h.role, 'verae-staff-iam'); const login = await fetch(`http://127.0.0.1:${port}/login`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ username: 'admin', password: 'admin-dev-key' }), }); assert.equal(login.status, 200); const { token, user } = await login.json(); assert.ok(user.permissions.includes('*')); const hdr = { authorization: `Bearer ${token}`, 'content-type': 'application/json' }; const ok = await fetch(`http://127.0.0.1:${port}/check?permission=cs.credit`, { headers: hdr }); assert.equal(ok.status, 200); const csLogin = await fetch(`http://127.0.0.1:${port}/login`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ username: 'cs', password: 'cs-dev-key' }), }); const cs = await csLogin.json(); const deny = await fetch(`http://127.0.0.1:${port}/check?permission=accounting.export`, { headers: { authorization: `Bearer ${cs.token}` }, }); assert.equal(deny.status, 403); const created = await fetch(`http://127.0.0.1:${port}/users`, { method: 'POST', headers: hdr, body: JSON.stringify({ username: 'pat', password: 'pat-pass-99', name: 'Pat', roles: ['sales'] }), }); assert.equal(created.status, 201); const body = await created.json(); assert.deepEqual(body.roles, ['sales']); const list = await (await fetch(`http://127.0.0.1:${port}/users`, { headers: hdr })).json(); assert.ok(list.users.some((u) => u.username === 'pat')); } finally { child.kill('SIGTERM'); } });