feat(api, web): enhance agent management and linting capabilities
Build and Push EvoFirewall Docker Image / build-and-push (push) Successful in 2m17s
Build and Push EvoFirewall Docker Image / create-release (push) Skipped

- Added a new linting command for OpenAPI specifications in the package.json, improving code quality checks.
- Updated frontend documentation to clarify component usage and structure, including detailed descriptions for `SettingsShell` and `Auth callback`.
- Refactored agent-related API routes to streamline control-plane functionalities, consolidating multiple routes for better organization.
- Improved error handling in the API to provide more informative responses for validation errors, enhancing user feedback during interactions.

These changes enhance the overall development experience and improve the management of agents within the application.
This commit is contained in:
Denozordec
2026-07-30 14:13:05 +07:00
parent fb95ef22b3
commit f160992d94
68 changed files with 3155 additions and 6899 deletions
+106
View File
@@ -0,0 +1,106 @@
import { describe, it, expect, afterAll } from 'vitest'
import { buildApp } from '../app.js'
import type { AppConfig } from '../config.js'
const testConfig: AppConfig = {
databaseUrl: 'sqlite::memory:',
jwtSecret: 'test',
jwtTtlHours: 24,
serverPort: 8080,
staticDir: null,
logLevel: 'error',
authRequired: false,
authIssuer: 'https://auth.test',
authPortalUrl: 'http://localhost:5175',
publicBaseUrl: 'https://fw.example.com',
enrollSeed: 'test-seed',
}
describe('agents CRUD critical paths', () => {
const appPromise = buildApp({ memory: true, config: testConfig })
afterAll(async () => {
const app = await appPromise
await app.close()
})
it('creates invite, approves, lists with install curl', async () => {
const app = await appPromise
await app.ready()
const created = await app.inject({
method: 'POST',
url: '/api/v1/install-links',
payload: { name: 'ops-01', platform: 'linux' },
})
expect(created.statusCode).toBe(201)
const link = created.json() as { agent_id: string }
const approve = await app.inject({
method: 'POST',
url: `/api/v1/agents/${link.agent_id}/approve`,
})
expect(approve.statusCode).toBe(200)
const list = await app.inject({ method: 'GET', url: '/api/v1/agents' })
expect(list.statusCode).toBe(200)
const items = (list.json() as { items: { id: string; status: string }[] })
.items
const agent = items.find((a) => a.id === link.agent_id)
expect(agent?.status).toBe('approved')
})
it('creates policy set + rule and reorders', async () => {
const app = await appPromise
await app.ready()
const setRes = await app.inject({
method: 'POST',
url: '/api/v1/policy-sets',
payload: { name: 'test-set' },
})
expect(setRes.statusCode).toBe(200)
const set = setRes.json() as { id: string }
const r1 = await app.inject({
method: 'POST',
url: '/api/v1/rules',
payload: {
set_id: set.id,
action: 'deny',
cidr: '1.1.1.1/32',
},
})
expect(r1.statusCode).toBe(200)
const rule1 = r1.json() as { id: string }
const r2 = await app.inject({
method: 'POST',
url: '/api/v1/rules',
payload: {
set_id: set.id,
action: 'allow',
cidr: '8.8.8.8/32',
},
})
expect(r2.statusCode).toBe(200)
const rule2 = r2.json() as { id: string }
const reorder = await app.inject({
method: 'PUT',
url: `/api/v1/policy-sets/${set.id}/rules/reorder`,
payload: {
ordered_ids: [rule2.id, rule1.id],
},
})
expect(reorder.statusCode).toBe(200)
const rules = await app.inject({
method: 'GET',
url: `/api/v1/policy-sets/${set.id}/rules`,
})
expect(rules.statusCode).toBe(200)
const items = (rules.json() as { items: { id: string }[] }).items
expect(items[0]?.id).toBe(rule2.id)
})
})