feat(api, web): implement short install link functionality for agents
- Added new API endpoints for creating, retrieving, and revoking install links for agents. - Enhanced the agent installation process with short links accessible via `/agent-install/:id` and `/:slug`. - Updated the README and documentation to reflect the new installation method and usage instructions. - Refactored relevant components in the web application to support the new install link feature. - Improved error handling and validation for install link operations. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
||||
createIpListBodySchema,
|
||||
createPolicyRuleBodySchema,
|
||||
createPolicySetBodySchema,
|
||||
createInstallLinkBodySchema,
|
||||
patchPolicySetBodySchema,
|
||||
putAgentPolicySetsBodySchema,
|
||||
patchAgentBodySchema,
|
||||
@@ -25,6 +26,10 @@ import {
|
||||
resolveAndStoreHostnameRule,
|
||||
resolveHostnameToCidrs,
|
||||
} from '../services/policy/resolve-hostname.js'
|
||||
import {
|
||||
mapInstallLink,
|
||||
randomToken,
|
||||
} from '../services/install-links.js'
|
||||
import type { AppConfig } from '../config.js'
|
||||
|
||||
function mapAgent(a: NonNullable<ReturnType<typeof repos.getAgent>>) {
|
||||
@@ -134,6 +139,41 @@ export const controlRoutes: FastifyPluginAsync<{ config: AppConfig }> = async (
|
||||
}
|
||||
})
|
||||
|
||||
// Install short-links
|
||||
app.get('/install-links', async () => ({
|
||||
items: repos
|
||||
.listInstallLinks(app.db)
|
||||
.map((row) => mapInstallLink(row, config.publicBaseUrl)),
|
||||
}))
|
||||
|
||||
app.post('/install-links', async (req, reply) => {
|
||||
const body = createInstallLinkBodySchema.parse(req.body)
|
||||
const id = randomToken(10)
|
||||
const slug = randomToken(16)
|
||||
if (repos.getInstallLink(app.db, id) || repos.getInstallLinkBySlug(app.db, slug)) {
|
||||
throw new AppError('CONFLICT', 'Retry create (id collision)', 409)
|
||||
}
|
||||
const row = repos.insertInstallLink(app.db, {
|
||||
id,
|
||||
slug,
|
||||
clientName: body.name.trim(),
|
||||
platform: body.platform ?? 'linux',
|
||||
createdAt: new Date().toISOString(),
|
||||
useCount: 0,
|
||||
})
|
||||
return reply.code(201).send(mapInstallLink(row!, config.publicBaseUrl))
|
||||
})
|
||||
|
||||
app.delete<{ Params: { id: string } }>(
|
||||
'/install-links/:id',
|
||||
async (req) => {
|
||||
const row = repos.getInstallLink(app.db, req.params.id)
|
||||
if (!row) throw new AppError('NOT_FOUND', 'Install link not found', 404)
|
||||
const updated = repos.revokeInstallLink(app.db, row.id)
|
||||
return mapInstallLink(updated!, config.publicBaseUrl)
|
||||
},
|
||||
)
|
||||
|
||||
// Agents
|
||||
app.get('/agents', async () => ({
|
||||
items: repos.listAgents(app.db).map(mapAgent),
|
||||
|
||||
Reference in New Issue
Block a user