feat(api): enhance agent scripts and enrollment process
Build and Push EvoFirewall Docker Image / build-and-push (push) Successful in 1m43s
Build and Push EvoFirewall Docker Image / create-release (push) Skipped

- Updated `evofw-firewall.sh` to handle empty deny/allow rule sets, allowing agents without rules to function correctly.
- Improved `install.sh` to ensure the sync script is downloaded before enrollment, with added validation for the script's content.
- Modified agent route to record `lastSeenAt` and `lastSeenIp` during enrollment and policy fetching, ensuring accurate tracking of agent status.
- Added tests to verify that approved agents can fetch an empty policy without rule sets.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Denozordec
2026-07-21 19:25:34 +07:00
co-authored by Cursor
parent 08e7c4d755
commit d516a9a093
4 changed files with 99 additions and 12 deletions
@@ -144,6 +144,63 @@ describe('install-links', () => {
expect(byId.body).toContain('/v1/agent/policy.rsc')
})
it('approved agent can fetch empty policy without rule sets', async () => {
const app = await appPromise
await app.ready()
const created = await app.inject({
method: 'POST',
url: '/api/v1/install-links',
payload: { name: 'empty-policy', platform: 'linux' },
})
const link = created.json() as { id: string; agent_id: string }
const token = 'evofw_empty_policy_token_abcdefgh'
const enroll = await app.inject({
method: 'POST',
url: '/v1/agent/enroll',
headers: {
'content-type': 'application/json',
'x-evofw-seed': 'test-seed',
},
payload: {
name: 'empty-policy',
platform: 'linux',
token,
install_link_id: link.id,
},
})
expect(enroll.statusCode).toBe(201)
await app.inject({
method: 'POST',
url: `/api/v1/agents/${link.agent_id}/approve`,
})
const policy = await app.inject({
method: 'GET',
url: '/v1/agent/policy',
headers: { authorization: `Bearer ${token}` },
})
expect(policy.statusCode).toBe(200)
const body = policy.json() as {
deny_cidrs: string[]
allow_cidrs: string[]
policy_mode: string
hash: string
}
expect(body.deny_cidrs).toEqual([])
expect(body.allow_cidrs).toEqual([])
expect(body.policy_mode).toBe('blacklist')
expect(body.hash).toMatch(/^sha256:/)
const agents = await app.inject({ method: 'GET', url: '/api/v1/agents' })
const row = (
agents.json() as { items: { id: string; last_seen_at: string | null }[] }
).items.find((a) => a.id === link.agent_id)
expect(row?.last_seen_at).toBeTruthy()
})
it('approved agent can fetch policy.rsc with address-list commands', async () => {
const app = await appPromise
await app.ready()