AkurAI Build
Menu

Public repository / aa0081daf17648c0a6e369ad847bdc30c0c7d321

AkurAI-Mail / src/routes/webmail/api/+server.ts

Latest change 66e3647948f2e277afdd6ecd16939de8b6ad525f - Initial commit: AkurAI Mail UI (SvelteKit+Bun) by Ólafur Búi Ólafsson

import { json } from "@sveltejs/kit";
import { isAuthenticated, mailboxFromSession } from "$lib/auth";
import { akurai } from "$lib/server";

const hits = new Map<string, number[]>();
const windowMs = 60_000;
const maxHits = 90;

function text(value: unknown) {
  return typeof value === "string" ? value : "";
}

function payload(value: unknown) {
  return JSON.stringify(value ?? {});
}

export async function GET({ cookies, url }) {
  const requestedEmail = text(url.searchParams.get("email"));
  const email = isAuthenticated(cookies) ? requestedEmail : mailboxFromSession(cookies);
  const folder = text(url.searchParams.get("folder")) || "Inbox";
  const query = text(url.searchParams.get("query"));
  if (!email) return json({ ok: false, error: "email is required" }, { status: 400 });
  return json(await akurai(["webmail-state", email, "--folder", folder, "--query", query]));
}

function rateLimit(key: string) {
  const now = Date.now();
  const rows = (hits.get(key) ?? []).filter((at) => now - at < windowMs);
  rows.push(now);
  hits.set(key, rows);
  return rows.length <= maxHits;
}

export async function POST({ cookies, request, url, getClientAddress }) {
  const origin = request.headers.get("origin");
  if (origin && origin !== url.origin) return json({ ok: false, error: "invalid origin" }, { status: 403 });
  if (!rateLimit(getClientAddress())) return json({ ok: false, error: "rate limit exceeded" }, { status: 429 });
  const body = await request.json();
  const requestedEmail = text(body.email);
  const email = isAuthenticated(cookies) ? requestedEmail : mailboxFromSession(cookies);
  if (!email) return json({ ok: false, error: "email is required" }, { status: 400 });

  if (body.action === "read") return json(await akurai(["webmail-read", email, text(body.id), "--mark-read"]));
  if (body.action === "send") return json(await akurai(["webmail-send", email, payload(body.message)]));
  if (body.action === "draft") return json(await akurai(["webmail-draft", email, payload(body.message)]));
  if (body.action === "message") {
    const args = ["webmail-action", email, text(body.id), text(body.messageAction)];
    if (body.target) args.push("--target", text(body.target));
    return json(await akurai(args));
  }
  if (body.action === "config") return json(await akurai(["webmail-config", email, text(body.kind), payload(body.value)]));
  if (body.action === "apply-rules") return json(await akurai(["webmail-apply-rules", email, "--folder", text(body.folder) || "Inbox"]));
  if (body.action === "export") return json(await akurai(["webmail-export", email]));
  if (body.action === "import") return json(await akurai(["webmail-import", email, payload(body.value)]));
  if (body.action === "attachment") return json(await akurai(["webmail-attachment", email, text(body.id), String(body.index ?? "")]));
  return json({ ok: false, error: "unknown action" }, { status: 400 });
}