166 lines · 6.5 KB
import { env } from "cloudflare:workers";
import { accountDb } from "./scoped-db";
import { locate, registerLocator } from "./scoped-db/locators";
import { badRequest, conflict } from "./errors";
import { assertBelowCap, CAPS } from "./limits";
import { consumeAuthToken, storeAuthToken } from "./auth-tokens";
import { SUPPORTED_ALGORITHMS, verifyAssertion, verifyRegistration } from "./webauthn";
import type { RelyingParty } from "./webauthn";
import { toBase64Url } from "~/lib/base64url";
import type { Viewer } from "~/lib/types";

const CHALLENGE_TTL_SECONDS = 5 * 60;
const CHALLENGE_BYTES = 32;
const CEREMONY_TIMEOUT_MS = 120_000;

type Purpose = "register" | "login" | "second-factor";

export type PasskeyCreationOptions = {
  challenge: string;
  rp: { id: string; name: string };
  user: { id: string; name: string; displayName: string };
  pubKeyCredParams: { type: "public-key"; alg: number }[];
  excludeCredentials: { type: "public-key"; id: string }[];
  timeout: number;
};

export type PasskeyRequestOptions = {
  challenge: string;
  rpId: string;
  allowCredentials: { type: "public-key"; id: string }[];
  timeout: number;
};

export type RegistrationPayload = {
  challenge: string;
  clientDataJSON: string;
  attestationObject: string;
  transports: string[];
};
export type AssertionPayload = {