39 lines · 1.4 KB
import { createServerFn } from "@tanstack/react-start";
import { z } from "zod";
import { requireViewer, viewerMiddleware } from "./middleware";
import { limitAccountWrite } from "~/server/limits";
import { addSigningKey, deleteSigningKey, listSigningKeys } from "~/server/security/signatures";

export const getSigningKeys = createServerFn({ method: "GET" })
  .middleware([viewerMiddleware])
  .handler(async ({ context }) => listSigningKeys(requireViewer(context.viewer).id));

export const createSigningKey = createServerFn({ method: "POST" })
  .middleware([viewerMiddleware])
  .validator(
    z.object({
      kind: z.enum(["ssh", "gpg"]),
      title: z.string().trim().min(1, "Title is required").max(100),
      publicKey: z
        .string()
        .trim()
        .min(1, "Paste a public key")
        .max(64 * 1024),
    }),
  )
  .handler(async ({ data, context }) => {
    const viewer = requireViewer(context.viewer);
    await limitAccountWrite(viewer);
    return addSigningKey(viewer.id, data.kind, data.title, data.publicKey);
  });

export const removeSigningKey = createServerFn({ method: "POST" })
  .middleware([viewerMiddleware])
  .validator(z.object({ id: z.string().min(1).max(64) }))
  .handler(async ({ data, context }) => {
    const viewer = requireViewer(context.viewer);
    await limitAccountWrite(viewer);
    await deleteSigningKey(viewer.id, data.id);
    return { ok: true };
  });