Add allowlisted diagnostic jobs and MG4 ADB plan
This commit is contained in:
+44
-1
@@ -8,6 +8,7 @@ import Fastify, { type FastifyInstance, type FastifyReply, type FastifyRequest }
|
||||
import { z } from "zod";
|
||||
import type { AppConfig } from "./config.js";
|
||||
import { openDatabase, type CompanionDatabase } from "./database.js";
|
||||
import { JobRunner } from "./jobs.js";
|
||||
import {
|
||||
clientAddress,
|
||||
CSRF_COOKIE,
|
||||
@@ -96,13 +97,18 @@ export async function buildApp(config: AppConfig): Promise<FastifyInstance> {
|
||||
}
|
||||
});
|
||||
const database = openDatabase(config.databasePath);
|
||||
const jobRunner = new JobRunner(database);
|
||||
|
||||
app.decorate("database", database);
|
||||
app.decorate("jobRunner", jobRunner);
|
||||
app.decorateRequest("authUser", null);
|
||||
await app.register(cookie);
|
||||
await app.register(rateLimit, { global: false });
|
||||
|
||||
app.addHook("onClose", async () => database.close());
|
||||
app.addHook("onClose", async () => {
|
||||
jobRunner.close();
|
||||
database.close();
|
||||
});
|
||||
app.addHook("onSend", async (_request, reply) => {
|
||||
reply.header("X-Content-Type-Options", "nosniff");
|
||||
reply.header("Referrer-Policy", "no-referrer");
|
||||
@@ -272,6 +278,39 @@ export async function buildApp(config: AppConfig): Promise<FastifyInstance> {
|
||||
return collectSystemStatus();
|
||||
});
|
||||
|
||||
app.get("/api/jobs", async (request, reply) => {
|
||||
if (!requireUser(request, reply)) return;
|
||||
return { jobs: jobRunner.listJobs() };
|
||||
});
|
||||
|
||||
app.get("/api/job-runs", async (request, reply) => {
|
||||
if (!requireUser(request, reply)) return;
|
||||
return { runs: jobRunner.listRuns() };
|
||||
});
|
||||
|
||||
app.get<{ Params: { id: string } }>("/api/job-runs/:id", async (request, reply) => {
|
||||
if (!requireUser(request, reply)) return;
|
||||
const run = jobRunner.getRun(request.params.id);
|
||||
if (!run) return reply.code(404).send({ error: { code: "RUN_NOT_FOUND", message: "Job run not found" } });
|
||||
return run;
|
||||
});
|
||||
|
||||
app.post<{ Params: { jobId: string } }>("/api/jobs/:jobId/runs", async (request, reply) => {
|
||||
if (!requireUser(request, reply)) return;
|
||||
if (!jobRunner.has(request.params.jobId)) {
|
||||
return reply.code(404).send({ error: { code: "JOB_NOT_FOUND", message: "Job is not available" } });
|
||||
}
|
||||
const run = jobRunner.enqueue(request.params.jobId, request.authUser!.id);
|
||||
audit(database, {
|
||||
actorUserId: request.authUser!.id,
|
||||
action: "job.enqueue",
|
||||
result: "success",
|
||||
ipAddress: clientAddress(request),
|
||||
details: { jobId: request.params.jobId, runId: run.id }
|
||||
});
|
||||
return reply.code(202).send(run);
|
||||
});
|
||||
|
||||
app.get("/api/system/update", async (request, reply) => {
|
||||
if (!requireUser(request, reply)) return;
|
||||
return readUpdateStatus(config);
|
||||
@@ -338,9 +377,13 @@ export async function buildApp(config: AppConfig): Promise<FastifyInstance> {
|
||||
};
|
||||
await sendStatus();
|
||||
const interval = setInterval(() => void sendStatus(), 10_000);
|
||||
const stopJobEvents = jobRunner.onRun((run) => {
|
||||
if (!closed) reply.raw.write(`event: job-run\ndata: ${JSON.stringify(run)}\n\n`);
|
||||
});
|
||||
request.raw.on("close", () => {
|
||||
closed = true;
|
||||
clearInterval(interval);
|
||||
stopJobEvents();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user