49 lines · 1.8 KB
import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { z } from "zod";
import { submitAdvisory } from "~/fns/advisories";
import { useAction } from "~/hooks/use-action";
import { AdvisoryForm } from "~/components/security/AdvisoryForm";
import { Panel } from "~/ui/Panel";
import { requireSignedIn } from "~/lib/route-guards";

export const Route = createFileRoute("/$owner/$repo/security/advisories/new")({
  beforeLoad: requireSignedIn,
  validateSearch: z.object({ mode: z.enum(["draft", "report"]).default("report") }),
  component: NewAdvisoryPage,
});

function NewAdvisoryPage() {
  const params = Route.useParams();
  const { mode } = Route.useSearch();
  const navigate = useNavigate();
  const submit = useAction(submitAdvisory, { invalidate: false });
  const isReport = mode === "report";
  return (
    <Panel title={isReport ? "Privately report a vulnerability" : "New draft security advisory"}>
      {isReport && (
        <p className="border-b border-kumo-hairline px-4 py-3 text-sm text-kumo-subtle">
          Only the repository maintainers and people they invite can see this report. Please do not disclose it publicly
          until a fix is available.
        </p>
      )}
      <AdvisoryForm
        owner={params.owner}
        repo={params.repo}
        initial={null}
        submitLabel={isReport ? "Submit report" : "Create draft"}
        pending={submit.pending}
        error={submit.error}
        onSubmit={async (advisory) => {
          const result = await submit.run({ data: { ...params, advisory, mode } });
          if (result) {
            await navigate({
              to: "/$owner/$repo/security/advisories/$ghsaId",