import assert from "node:assert/strict" import test from "node:test" import { createHash } from "node:crypto" import Fastify from "fastify" import { PgDialect } from "drizzle-orm/pg-core" import routes from "../src/routes/instanceAgents" const id = "b48c0e33-1abd-4b11-89fa-1bb7b39a3057" async function fixture(isAdmin: boolean) { const updates: any[] = [] const app = Fastify() app.addHook("onRequest", async (request) => { request.user = { is_admin: isAdmin } as any }) app.decorate("db", { update: () => ({ set: (data: any) => ({ where: (condition: any) => ({ returning: async () => { if (new PgDialect().sqlToQuery(condition).params[0] !== id) return [] updates.push(data) return [{ id }] } }) }) }), }) await app.register(routes) return { app, updates } } test("only administrators can rotate an agent token", async (t) => { const f = await fixture(false) t.after(() => f.app.close()) const response = await f.app.inject({ method: "POST", url: "/instance-agents/" + id + "/token" }) assert.equal(response.statusCode, 403) assert.equal(f.updates.length, 0) }) test("rotation returns a new token, stores only its hash and requires a new heartbeat", async (t) => { const f = await fixture(true) t.after(() => f.app.close()) const tokens = [] for (let i = 0; i < 2; i++) { const response = await f.app.inject({ method: "POST", url: "/instance-agents/" + id + "/token" }) assert.equal(response.statusCode, 200) assert.equal(response.headers["cache-control"], "no-store") const { token } = response.json() assert.match(token, /^fedeo_agent_[a-f0-9]{64}$/) assert.equal(f.updates[i].tokenHash, createHash("sha256").update(token).digest("hex")) assert.equal(f.updates[i].tokenPrefix, token.slice(0, 24)) assert.equal(f.updates[i].lastSeenAt, null) assert.equal(f.updates[i].token, undefined) tokens.push(token) } assert.notEqual(tokens[0], tokens[1]) }) test("unknown agents cannot receive setup credentials", async (t) => { const f = await fixture(true) t.after(() => f.app.close()) const response = await f.app.inject({ method: "POST", url: "/instance-agents/00000000-0000-4000-8000-000000000000/token" }) assert.equal(response.statusCode, 404) assert.equal(f.updates.length, 0) })