GitFOSS
.ts
TypeScript
(application/typescript)
// std
import { join, resolve } from "node:path";
// 1st-party
import type { ServiceMethodFactory } from "@ethicdevs/react-monolith";
import { GitServer } from "@ethicdevs/fastify-git-server";
// app
import type { GitServerServiceDeps } from "./types";
import { Env } from "../../env";
import { ResourceVisibility } from "@prisma/client";

const makeRepositoryResolver: ServiceMethodFactory<
  GitServerServiceDeps,
  [string],
  PromiseLike<GitServer.RepositoryResolverResult>
> = ({ request }) => {
  return async (repoPath) => {
    const [orgSlug, repoSlug] = repoPath.split("/");

    const org = await request.prisma.organization.findUnique({
      where: {
        slug: orgSlug,
      },
    });

    if (org == null) {
      throw new Error(`Unknown organization "${org}".`);
    }

    const repo = await request.prisma.repository.findFirst({
      include: {
        organization: true,
      },
      where: {
        slug: repoSlug,
        organization: {
          slug: orgSlug,
        },
      },
    });

    if (repo == null) {
      throw new Error(
        `Unknown repository "${repo}" in (known) organization "${org}".`
      );
    }

    // /!\ Notice how it use db's data instead of user's input to build path.
    const gitRepositoryDir = resolve(
      join(Env.GIT_REPOSITORIES_ROOT, org.slug, repo.slug)
    );

    if (
      repo.visibility === ResourceVisibility.PUBLIC ||
      repo.visibility === ResourceVisibility.UNLISTED
    ) {
      return {
        authMode: GitServer.AuthMode.PUSH_ONLY,
        gitRepositoryDir,
      };
    } else {
      return {
        authMode: GitServer.AuthMode.ALWAYS,
        gitRepositoryDir,
      };
    }
  };
};

export default makeRepositoryResolver;