{"version":3,"file":"l402.cjs","sources":["../../../src/402/l402/utils.ts","../../../src/402/l402/l402.ts","../../../src/402/l402/server/l402.ts","../../../src/402/l402/server/utils.ts"],"sourcesContent":["interface WwwAuthenticatePayload {\n  token: string;\n  invoice: string;\n  [key: string]: string; // Allows any other string properties\n}\n\n/**\n * Client: parse \"www-authenticate\" header from server response\n * @param input\n * @returns details from the header value (token or macaroon, invoice)\n */\nexport const parseL402 = (input: string): WwwAuthenticatePayload => {\n  // Remove the L402 and LSAT identifiers\n  const string = input.replace(\"L402\", \"\").replace(\"LSAT\", \"\").trim();\n\n  // Initialize an object to store the key-value pairs\n  const keyValuePairs: Record<string, string> = {};\n\n  // Regular expression to match key and (quoted or unquoted) value\n  const regex = /(\\w+)=(\"([^\"]*)\"|'([^']*)'|([^,]*))/g;\n  let match;\n\n  // Use regex to find all key-value pairs\n  while ((match = regex.exec(string)) !== null) {\n    // Key is always match[1]\n    // Value is either match[3] (double-quoted), match[4] (single-quoted), or match[5] (unquoted)\n    keyValuePairs[match[1]] = match[3] || match[4] || match[5];\n  }\n\n  if (!keyValuePairs[\"token\"] && keyValuePairs[\"macaroon\"]) {\n    // fallback to old naming\n    keyValuePairs[\"token\"] = keyValuePairs[\"macaroon\"];\n    delete keyValuePairs[\"macaroon\"];\n  }\n\n  if (\n    !(\"token\" in keyValuePairs) ||\n    typeof keyValuePairs[\"token\"] !== \"string\"\n  ) {\n    throw new Error(\"No macaroon or token found in www-authenticate header\");\n  }\n  if (\n    !(\"invoice\" in keyValuePairs) ||\n    typeof keyValuePairs[\"invoice\"] !== \"string\"\n  ) {\n    throw new Error(\"No invoice found in www-authenticate header\");\n  }\n\n  return keyValuePairs as WwwAuthenticatePayload;\n};\n","import { Wallet } from \"../utils\";\nimport { parseL402 } from \"./utils\";\n\nexport const handleL402Payment = async (\n  l402Header: string,\n  url: string,\n  fetchArgs: RequestInit,\n  headers: Headers,\n  wallet: Wallet,\n): Promise<Response> => {\n  const details = parseL402(l402Header);\n  const token = details.token || details.macaroon;\n  const invoice = details.invoice;\n\n  if (!token) {\n    throw new Error(\"L402: missing token/macaroon in WWW-Authenticate header\");\n  }\n  if (!invoice) {\n    throw new Error(\"L402: missing invoice in WWW-Authenticate header\");\n  }\n\n  const invResp = await wallet.payInvoice({ invoice });\n  headers.set(\"Authorization\", `L402 ${token}:${invResp.preimage}`);\n  return fetch(url, fetchArgs);\n};\n\nexport const fetchWithL402 = async (\n  url: string,\n  fetchArgs: RequestInit,\n  options: {\n    wallet: Wallet;\n  },\n) => {\n  const wallet = options.wallet;\n  if (!wallet) {\n    throw new Error(\"wallet is missing\");\n  }\n  if (!fetchArgs) {\n    fetchArgs = {};\n  }\n  fetchArgs.cache = \"no-store\";\n  fetchArgs.mode = \"cors\";\n  const headers = new Headers(fetchArgs.headers ?? undefined);\n  fetchArgs.headers = headers;\n\n  const initResp = await fetch(url, fetchArgs);\n  const header = initResp.headers.get(\"www-authenticate\");\n  if (!header) {\n    return initResp;\n  }\n\n  return handleL402Payment(header, url, fetchArgs, headers, wallet);\n};\n","export type MacaroonPayload<T> = T & {\n  paymentHash: string; // hex — SHA256 of the preimage\n};\n\nexport async function issueL402Macaroon<T extends Record<string, unknown>>(\n  secret: string,\n  paymentHash: string,\n  params?: T,\n): Promise<string> {\n  if (\n    params !== undefined &&\n    Object.prototype.hasOwnProperty.call(params, \"paymentHash\")\n  ) {\n    throw new Error(\"paymentHash is reserved\");\n  }\n  const payload = { ...params, paymentHash } as MacaroonPayload<T>;\n  const encoded = Buffer.from(JSON.stringify(payload)).toString(\"base64url\");\n  const mac = await sign(secret, encoded);\n  return `${encoded}.${mac}`;\n}\n\nexport async function verifyL402Macaroon<T = unknown>(\n  secret: string,\n  token: string,\n): Promise<MacaroonPayload<T>> {\n  const { timingSafeEqual } = await import(\"crypto\");\n  const dotIndex = token.lastIndexOf(\".\");\n  if (dotIndex === -1) throw new Error(\"Invalid macaroon token\");\n\n  const encoded = token.slice(0, dotIndex);\n  const mac = token.slice(dotIndex + 1);\n\n  // Constant-time comparison to prevent timing attacks\n  const expectedMac = await sign(secret, encoded);\n  try {\n    if (\n      !timingSafeEqual(Buffer.from(mac, \"hex\"), Buffer.from(expectedMac, \"hex\"))\n    ) {\n      throw new Error(\"Invalid macaroon token\");\n    }\n  } catch (e) {\n    throw new Error(\"Invalid macaroon token\");\n  }\n\n  try {\n    const parsed: unknown = JSON.parse(\n      Buffer.from(encoded, \"base64url\").toString(\"utf8\"),\n    );\n    if (\n      parsed === null ||\n      typeof parsed !== \"object\" ||\n      Array.isArray(parsed) ||\n      typeof (parsed as Record<string, unknown>).paymentHash !== \"string\"\n    ) {\n      throw new Error(\"Invalid macaroon payload\");\n    }\n    return parsed as MacaroonPayload<T>;\n  } catch {\n    throw new Error(\"Invalid macaroon token\");\n  }\n}\n\nasync function sign(secret: string, payload: string): Promise<string> {\n  const { createHmac } = await import(\"crypto\");\n  return createHmac(\"sha256\", secret).update(payload).digest(\"hex\");\n}\n","/**\n * Server: create a WWW-Authenticate header for a given macaroon and invoice\n * @param args the macaroon/token and invoice generated for the client's request\n * @returns the header value\n */\nexport const makeL402AuthenticateHeader = (args: {\n  token?: string;\n  invoice: string;\n}) => {\n  if (!args.token) {\n    throw new Error(\"token must be provided\");\n  }\n\n  return `L402 version=\"0\" token=\"${args.token}\", invoice=\"${args.invoice}\"`;\n};\n\n/**\n * Server: parse \"authorization\" header sent from client\n * @param input value from authorization header\n * @returns the macaroon and preimage\n */\nexport function parseL402Authorization(\n  input: string,\n): { token: string; preimage: string } | null {\n  // Backwards compat: LSAT was the former name of L402\n  const normalized = input.replace(/^LSAT /, \"L402 \");\n  const prefix = \"L402 \";\n  if (!normalized.startsWith(prefix)) return null;\n  const credentials = normalized.slice(prefix.length);\n  const colonIndex = credentials.indexOf(\":\");\n  if (colonIndex === -1) {\n    throw new Error(\"Invalid authorization header value\");\n  }\n  return {\n    token: credentials.slice(0, colonIndex),\n    preimage: credentials.slice(colonIndex + 1),\n  };\n}\n"],"names":[],"mappings":"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"}