import Prisma from "@prisma/client"; import { log } from "../logs.js"; const prisma = new Prisma.PrismaClient(); export async function listPermissions(sessionToken) { const session = await prisma.session.findUnique({ where: { token: sessionToken, }, include: { appliedKeys: true, }, }); if (!session) return []; const perms = []; for (const key of session.appliedKeys) { if (key.validUntil && new Date() > key.validUntil) continue; for (const perm of key.permissions) { perms.push(perm); } } return perms; } export async function hasPermission(sessionToken, permission, forValue) { let hasPermission = false; for (const perm of await listPermissions(sessionToken)) { if (perm == permission) hasPermission = true; else if (perm == permission + ":" + forValue) hasPermission = true; } return hasPermission; } export async function checkAdmin(req, res, next) { if (!(await hasPermission(req.locals.session, "admin"))) { res.status(401).send({ success: false, error: "admin_only", message: "You need to be admin to do this!", }); return; } next(); } export async function applyKey(sessionToken, key) { if (!key) return false; const foundKey = await prisma.key.findUnique({ where: { key, }, }); if (!foundKey) return false; await prisma.session.update({ where: { token: sessionToken, }, data: { appliedKeys: { connect: { key: foundKey.key, }, }, }, }); return true; } export async function revokeKey(sessionToken, key) { if (!key) return false; await prisma.session.update({ where: { token: sessionToken, }, data: { appliedKeys: { disconnect: { key: key, }, }, }, }); return true; } // Clean up expired keys every hour setInterval( async () => { const keys = await prisma.key.findMany(); for (const key of keys) { if (key.validUntil && key.validUntil < new Date()) { log( "API / Permissions", `Removed expired key: ${key.key}; Permissions: ${key.permissions.join( ", ", )}`, ); await prisma.key.delete({ where: { key: key.key, }, }); } } }, 1000 * 60 * 60, );