217 lines · 10.1 KB
import { z } from "zod";
import { peekAuthToken, storeAuthToken } from "../auth-tokens";
import { randomToken } from "../crypto";
import { badRequest, forbidden, HttpError, unauthorized } from "../errors";
import { publicUrl } from "../events/emit";
import { authenticatedRemote, mintRepoToken } from "../git/artifacts";
import { limitWrite } from "../limits";
import { hasPermission, loadRepoById, repoPermission } from "../repos";
import { loadUserById, toViewer } from "../auth";
import { containerLimits, containersEnabled, containerStub } from "./container-config";
import { CONTAINERS_PAID_ONLY, containerUsage, EDITOR_METER } from "./container-meter";
import { remainingQuota } from "../metering/quota";
import { json } from "./http";
import { editorOriginFor } from "./origin";
import { editorRoomStub } from "./room-client";
import { canWrite, EDITOR_TOKEN_PREFIX, resolveEditorToken } from "./session";
import type { EditorSession } from "./session";
import { EDITOR_WS_PROTOCOL } from "~/lib/editor-protocol";

const PREVIEW_PREFIX = "gitfor_pvw";
/** Short: the ticket is a bearer in the URL, so a leaked link must go stale before it can be reused. */
const PREVIEW_TTL_SECONDS = 5 * 60;
/** Response headers the previewed (user-controlled) app may set on the editor origin; everything else is dropped. */
const PREVIEW_RESPONSE_HEADERS = new Set([
  "content-type",
  "content-length",
  "content-encoding",
  "cache-control",
  "etag",
  "last-modified",
  "vary",
]);
const HTTP_REDIRECT_MIN = 300;
const HTTP_REDIRECT_MAX = 400;
const UNLIMITED_ATTEMPTS = Number.MAX_SAFE_INTEGER;
const HTTP_PAYMENT_REQUIRED = 402;
const HTTP_TOO_MANY = 429;
const MAX_PORT = 65535;
const SECONDS_PER_MINUTE = 60;
const SECONDS_PER_HOUR = 3600;