58 lines
2.4 KiB
TypeScript
58 lines
2.4 KiB
TypeScript
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)
|
|
})
|