232 lines · 9.4 KB
import { createServerFn } from "@tanstack/react-start";
import { z } from "zod";
import { requireViewer, viewerMiddleware } from "./middleware";
import { accountDb } from "~/server/scoped-db";
import { forgetLocator } from "~/server/scoped-db/locators";
import { revokeAccessTokensWhere } from "~/server/access-token-store";
import { createSession, listSessions, loadUserById, revokeSession } from "~/server/auth";
import { enforceRateLimit, limitAccountWrite } from "~/server/limits";
import { conflict, notFoundError } from "~/server/errors";
import { confirmPassword, notifySecurityEvent, revokeAllSessions } from "~/server/account-security";
import {
  disableTotp,
  enableTotp,
  regenerateRecoveryCodes,
  remainingRecoveryCodes,
  requiresSecondFactor,
  startTotpSetup,
} from "~/server/two-factor";
import { passkeyCreationOptions, registerPasskey } from "~/server/passkeys";
import { email } from "~/lib/validation";
import { devMailPreviewUrl } from "~/server/notify/dev-mail";
import {
  addAccountEmail,
  listAccountEmails,
  removeAccountEmail,
  resendAccountEmailVerification,
  setPrimaryAccountEmail,
} from "~/server/user-emails";

const encoded = z.string().min(1).max(16384);
const sudo = z.object({ password: z.string().max(200) });

export const getSecuritySettings = createServerFn({ method: "GET" })
  .middleware([viewerMiddleware])
  .handler(async ({ context }) => {
    const viewer = requireViewer(context.viewer);
    const user = await loadUserById(viewer.id);
    if (!user) throw notFoundError("Account not found");
    const passkeys = await accountDb(viewer.id).all<{
      id: string;