import { createHmac, timingSafeEqual } from "node:crypto";

export function isComposeExitKey(value: string) {
  return /^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/.test(value);
}

function sign(payload: string) {
  const secret = process.env.OFFICIAL_MAIL_CRON_SECRET;
  if (!secret) throw new Error("compose-exit-secret-missing");
  return createHmac("sha256", secret).update(`compose-exit:${payload}`).digest("base64url");
}

// This capability can only create one draft, never send mail or read an account.
export function createComposeExitGrant(email: string, key: string) {
  const payload = Buffer.from(JSON.stringify({ email, key, expires: Date.now() + 24 * 60 * 60 * 1000 })).toString("base64url");
  return `${payload}.${sign(payload)}`;
}

export function readComposeExitGrant(token: string, key: string): string | null {
  try {
    const [payload, signature, extra] = token.split(".");
    if (!payload || !signature || extra || token.length > 2048) return null;
    const expected = Buffer.from(sign(payload));
    const actual = Buffer.from(signature);
    if (actual.length !== expected.length || !timingSafeEqual(actual, expected)) return null;
    const value = JSON.parse(Buffer.from(payload, "base64url").toString("utf8"));
    return value.key === key && typeof value.email === "string" && value.expires > Date.now() ? value.email : null;
  } catch {
    return null;
  }
}
