32 lines · 1.3 KB
import { listRefs, branchSha } from "../git/refs";
import { withStore } from "../git/store";
import { renderMarkdown } from "../markdown";
import type { RepoRow } from "~/lib/types";

const POLICY_PATHS = ["SECURITY.md", ".github/SECURITY.md", "docs/SECURITY.md"];
const MAX_POLICY_BYTES = 256 * 1024;

/** Finds SECURITY.md in the locations GitHub honours, on the default branch. */
export async function loadSecurityPolicy(repo: RepoRow): Promise<{ path: string; html: string } | null> {
  const sha = branchSha(await listRefs(repo), repo.default_branch);
  if (!sha) return null;
  return withStore(repo.artifacts_name, async (store) => {
    const commit = await store.commit(sha);
    if (!commit) return null;
    for (const path of POLICY_PATHS) {
      const entry = await store.entryAtPath(commit.treeSha, path);
      if (!entry || entry.type !== "blob") continue;
      const blob = await store.blob(entry.sha);
      if (!blob || blob.byteLength > MAX_POLICY_BYTES) return null;
      const html = renderMarkdown(new TextDecoder().decode(blob), {
        owner: repo.owner_name,
        repo: repo.name,
        ref: repo.default_branch,
        basePath: path.includes("/") ? path.slice(0, path.lastIndexOf("/")) : "",
      });
      return { path, html };
    }
    return null;
  });
}