2025-08-13 04:31:07 -08:00

142 lines
3.2 KiB
TypeScript

import { PrismaClient, Prisma } from '../../generated/prisma'
import { withAccelerate } from "@prisma/extension-accelerate"
import { type FastifyInstance, type FastifyReply, type FastifyRequest } from 'fastify'
import { env } from '../config/env'
import { constants } from '../config/constants'
import { isAdmin } from '../utils/privs'
import { makeWorkerUtils, WorkerUtils } from 'graphile-worker'
import logger from '../utils/logger'
import { } from '../../generated/prisma'
const prisma = new PrismaClient().$extends(withAccelerate())
interface JobRow {
id: number;
queue_name: string | null;
task_identifier: string;
priority: number;
run_at: Date;
attempts: number;
max_attempts: number;
last_error: string | null;
created_at: Date;
updated_at: Date;
key: string | null;
locked_at: Date | null;
locked_by: string | null;
revision: number;
flags: string | null;
}
async function getJobs() {
const jobs = await prisma.$queryRaw<JobRow[]>(
Prisma.sql`
SELECT
id,
queue_name,
task_identifier,
priority,
run_at,
attempts,
max_attempts,
last_error,
created_at,
updated_at,
key,
locked_at,
locked_by,
revision,
flags
FROM graphile_worker.jobs
ORDER BY id DESC
LIMIT 2500
`
);
return jobs;
}
export default async function adminRoutes(fastify: FastifyInstance): Promise<void> {
fastify.get('/admin', async function (request, reply) {
const userId = request.session.get('userId');
if (!userId) {
throw new Error('No user is logged in.');
}
const user = await prisma.user.findUnique({
where: { id: userId },
include: { roles: true }
});
if (!user) throw new Error('User not found.');
if (!isAdmin(user)) {
return reply.status(403).send("you are not a jedi, yet");
} else {
const jobs = await getJobs();
logger.debug(jobs[0])
return reply.viewAsync("admin.hbs", {
jobs,
user,
site: constants.site,
}, { layout: 'layouts/main.hbs' });
}
})
fastify.delete('/admin/jobs', async function (request, reply) {
const userId = request.session.get('userId')
const user = await prisma.user.findUnique({
where: { id: userId },
include: {
roles: true
}
})
if (!user) throw new Error('User not found.');
if (isAdmin(user)) {
let workerUtils: WorkerUtils | undefined;
try {
const workerUtils = await makeWorkerUtils({ connectionString: env.DATABASE_URL });
const jobIdsResult = await prisma.$queryRaw<{ id: number }[]>(
Prisma.sql`SELECT id FROM graphile_worker.jobs`
);
const jobIds: string[] = jobIdsResult.map(j => '' + j.id);
logger.warn(`Permanently failing all graphile-worker jobs on behalf of ${user.id}.`);
if (jobIds.length > 0) {
await workerUtils.permanentlyFailJobs(jobIds, 'Job deleted by admin');
}
}
finally {
if (workerUtils) {
await workerUtils.release();
}
}
}
return reply.viewAsync("admin.hbs", {
user,
site: constants.site,
notification: 'Jobs beleted!',
});
})
}