Skip to content
admin.ts 27.1 KiB
Newer Older
Grant's avatar
Grant committed
    .doing(hasExistingBan ? "BAN_UPDATE" : "BAN_CREATE")
    .reason(req.header("X-Audit") || null)
    .withComment(
      hasExistingBan
        ? `Updated ban for ${instance.hostname}`
        : `Created a ban for ${instance.hostname}`
    )
    .withBan(ban)
    .create();
Grant's avatar
Grant committed
    ban,
Grant's avatar
Grant committed
    auditLog,
Grant's avatar
Grant committed
/**
 * Delete an instance ban
 *
 * @header X-Audit
 * @param :domain The instance domain
 */
app.delete("/instance/:domain/ban", async (req, res) => {
  // unban domain & subdomains

  let instance: Instance;

  try {
    instance = await Instance.fromDomain(req.params.domain);
  } catch (e) {
    if (e instanceof InstanceNotFound) {
      res.status(404).json({ success: false, error: "instance not found" });
    } else {
      Logger.error(
        `/instance/${req.params.domain}/ban Error ` + (e as any)?.message
      );
      res.status(500).json({ success: false, error: "Internal error" });
    }
    return;
  }

Grant's avatar
Grant committed
  let ban;
Grant's avatar
Grant committed
    ban = await instance.unban();
  } catch (e) {
    if (e instanceof InstanceNotBanned) {
      res.status(404).json({ success: false, error: "instance not banned" });
    } else {
      Logger.error(
        `/instance/${req.params.domain}/ban Error ` + (e as any)?.message
      );
      res.status(500).json({ success: false, error: "Internal error" });
    }
    return;
  }

Grant's avatar
Grant committed
  const user = (await User.fromAuthSession(req.session.user!))!;
Grant's avatar
Grant committed
  const auditLog = await AuditLog.Factory(user.sub)
Grant's avatar
Grant committed
    .doing("BAN_DELETE")
    .reason(req.header("X-Audit") || null)
    .withComment(`Deleted ban for ${instance.hostname}`)
    .create();
Grant's avatar
Grant committed
  res.json({ success: true, auditLog });
Grant's avatar
Grant committed
});

/**
 * Get all audit logs
 *
 * TODO: pagination
 */
app.get("/audit", async (req, res) => {
  const auditLogs = await prisma.auditLog.findMany({
    orderBy: {
      createdAt: "desc",
    },
  });

  res.json({ success: true, auditLogs });
});

/**
 * Get audit log entry by ID
 *
 * @param :id Audit log ID
 */
app.get("/audit/:id", async (req, res) => {
  let id = parseInt(req.params.id);

  if (isNaN(id)) {
    return res
      .status(400)
      .json({ success: false, error: "id is not a number" });
  }

  const auditLog = await prisma.auditLog.findFirst({ where: { id } });

  if (!auditLog) {
    return res
      .status(404)
      .json({ success: false, error: "Audit log not found" });
  }

  res.json({ success: true, auditLog });
});

/**
 * Update audit log reason
 *
 * @param :id Audit log id
 * @body reason string|null
 */
app.put("/audit/:id/reason", async (req, res) => {
  let id = parseInt(req.params.id);
  let reason: string;

  if (isNaN(id)) {
    return res
      .status(400)
      .json({ success: false, error: "id is not a number" });
  }

  if (typeof req.body.reason !== "string" && req.body.reason !== null) {
    return res
      .status(400)
      .json({ success: false, error: "reason is not a string or null" });
  }

  reason = req.body.reason;

  const auditLog = await prisma.auditLog.findFirst({
    where: {
      id,
    },
  });

  if (!auditLog) {
    return res
      .status(404)
      .json({ success: false, error: "audit log is not found" });
  }

  const newAudit = await prisma.auditLog.update({
    where: { id },
    data: {
      reason,
      updatedAt: new Date(),
    },
  });

  res.json({
    success: true,
    auditLog: newAudit,
  });
Grant's avatar
Grant committed
export default app;