466 lines · 20.6 KB
import { claimSignupSeat, releaseWaitlistSpot, seatGuard, SIGNUPS_FULL } from "./waitlist";
import { accountDb, stmt as scopedStmt } from "./scoped-db";
import { forgetLocator, registerLocator } from "./scoped-db/locators";
import { scopedId } from "./scoped-db/ids";
import { registerInviter } from "./invitation-index";
import { dropAccountState } from "./account-scope";
import { accountsById } from "./people";
import { env } from "cloudflare:workers";
import { all, batch, first, run, stmt } from "./db";
import { hashPassword, randomId } from "./crypto";
import { badRequest, conflict, forbidden, notFoundError } from "./errors";
import { canAdministerAccount } from "./repos";
import { scheduleRevocationSweep, sweepRevokedOrgAccess } from "./pull-guard";
import type { OrgDefaultPermission } from "./repos";
import { assertBelowCap } from "./limits";
import { assertVerifiedForWrites } from "./verified-writes";
import { purgeOrgFollowers, revokeDeployTokensCreatedBy } from "./access-revocation";
import type { Viewer } from "~/lib/types";
import { isAdminClaimableName, isReservedName } from "~/lib/reserved-names";
import { cleanDisplayName } from "~/lib/validation";
import { captureServerEvent } from "./analytics";
import { isAdminEmail, mayBootstrapAdminAtSignup, mayBypassClosedSignups } from "./admin-bootstrap";
import { userChanged } from "./user-row";

/** Names that still redirect stay retired so old URLs and git remotes can't be taken over; only their owner may reclaim one. */
export async function accountNameTaken(
  name: string,
  reclaimingAccountId: string | null = null,
  allowReserved = false,
): Promise<boolean> {
  if (isReservedName(name) && !allowReserved) return true;
  if ((await first<{ id: string }>("SELECT id FROM accounts WHERE name = ?", name)) !== null) return true;
  if ((await first("SELECT 1 AS ok FROM retired_account_names WHERE name = ? COLLATE NOCASE", name)) !== null) {
    return true;
  }
  const redirect = await first<{ account_id: string }>(
    "SELECT account_id FROM account_redirects WHERE old_name = ? COLLATE NOCASE",
    name,
  );
  return redirect !== null && redirect.account_id !== reclaimingAccountId;