Files
2026-10-12 14:25:22 +02:00

91 lines
2.9 KiB
TypeScript

import type { HttpContext } from '@adonisjs/core/http'
import vpsConfig from '#config/vps'
import CaddyfileVersion from '#models/caddyfile_version'
import UserError from '#exceptions/user_error'
import caddyService, { parseCaddyfile, type ReloadResult } from '#services/caddy_service'
import siteMonitor from '#services/site_monitor'
import { actor, audit } from '#services/audit'
import { updateCaddyfileValidator } from '#validators/caddy'
export default class CaddyController {
async show() {
const content = await caddyService.read()
return {
path: vpsConfig.caddy.caddyfilePath,
container: vpsConfig.caddy.container,
content,
sites: parseCaddyfile(content),
}
}
async update(ctx: HttpContext) {
const { content, reason } = await ctx.request.validateUsing(updateCaddyfileValidator)
const result = await caddyService.saveAndReload(content, {
username: actor(ctx).username,
reason: reason || 'Modification manuelle',
})
return this.#respond(ctx, 'Modification du Caddyfile', result)
}
async reload(ctx: HttpContext) {
const result = await caddyService.reload()
return this.#respond(ctx, 'Rechargement de Caddy', result)
}
async versions() {
const versions = await CaddyfileVersion.query()
.select('id', 'username', 'reason', 'created_at')
.orderBy('id', 'desc')
return versions.map((version) => ({
id: version.id,
username: version.username,
reason: version.reason,
createdAt: version.createdAt.toISO(),
}))
}
async version({ params }: HttpContext) {
const version = await CaddyfileVersion.find(params.id)
if (!version) throw new UserError('Version introuvable.', 404)
return {
id: version.id,
username: version.username,
reason: version.reason,
createdAt: version.createdAt.toISO(),
content: version.content,
}
}
async restore(ctx: HttpContext) {
const version = await CaddyfileVersion.find(ctx.params.id)
if (!version) throw new UserError('Version introuvable.', 404)
const result = await caddyService.saveAndReload(version.content, {
username: actor(ctx).username,
reason: `Restauration de la version #${version.id}`,
})
return this.#respond(ctx, `Restauration du Caddyfile (#${version.id})`, result)
}
async #respond(ctx: HttpContext, action: string, result: ReloadResult) {
await audit(ctx, {
action,
target: vpsConfig.caddy.caddyfilePath,
status: result.ok ? 'success' : 'error',
output: result.output,
})
if (!result.ok) {
return ctx.response.unprocessableEntity({
message: 'Caddy a refusé la configuration : le Caddyfile est inchangé.',
output: result.output,
})
}
/**
* New or removed domains show up right away on the sites page.
*/
siteMonitor.sync().catch(() => {})
return { ok: true, output: result.output }
}
}