{"version":3,"file":"net.cjs","names":["hashjs","removeSigningKeyPrefix"],"sources":["../../src/helpers/net.ts"],"sourcesContent":["import canonicalize from \"canonicalize\";\nimport hashjs from \"hash.js\";\nimport type { Logger } from \"../middleware/logger.ts\";\nimport { logOnce } from \"./log.ts\";\nimport { removeSigningKeyPrefix } from \"./strings.ts\";\n\nconst { hmac, sha256 } = hashjs;\n\n/**\n * Send an HTTP request with the given signing key. If the response is a 401 or\n * 403, then try again with the fallback signing key\n */\nexport async function fetchWithAuthFallback<TFetch extends typeof fetch>({\n  authToken,\n  authTokenFallback,\n  fetch,\n  options,\n  url,\n}: {\n  authToken?: string;\n  authTokenFallback?: string;\n  fetch: TFetch;\n  options?: Parameters<TFetch>[1];\n  url: URL | string;\n}): Promise<Response> {\n  let res = await fetch(url, {\n    ...options,\n    headers: {\n      ...options?.headers,\n      Authorization: `Bearer ${authToken}`,\n    },\n  });\n\n  if ([401, 403].includes(res.status) && authTokenFallback) {\n    res = await fetch(url, {\n      ...options,\n      headers: {\n        ...options?.headers,\n        Authorization: `Bearer ${authTokenFallback}`,\n      },\n    });\n  }\n\n  return res;\n}\n\nexport function signWithHashJs(\n  data: unknown,\n  signingKey: string,\n  ts: string,\n): string {\n  // Calculate the HMAC of the request body ourselves.\n  // We make the assumption here that a stringified body is the same as the\n  // raw bytes; it may be pertinent in the future to always parse, then\n  // canonicalize the body to ensure it's consistent.\n  const encoded = typeof data === \"string\" ? data : canonicalize(data);\n  // biome-ignore lint/suspicious/noExplicitAny: intentional\n  const mac = hmac(sha256 as any, removeSigningKeyPrefix(signingKey))\n    .update(encoded)\n    .update(ts)\n    .digest(\"hex\");\n\n  return mac;\n}\n\n// Cache for CryptoKeys to avoid repeated importKey calls\nconst cryptoKeyCache = new Map<string, CryptoKey>();\n\nasync function signWithNative(\n  subtle: SubtleCrypto,\n  data: unknown,\n  signingKey: string,\n  ts: string,\n): Promise<string> {\n  const encoded = typeof data === \"string\" ? data : canonicalize(data);\n  const key = removeSigningKeyPrefix(signingKey);\n\n  let cryptoKey = cryptoKeyCache.get(key);\n  if (!cryptoKey) {\n    cryptoKey = await subtle.importKey(\n      \"raw\",\n      new TextEncoder().encode(key),\n      { name: \"HMAC\", hash: \"SHA-256\" },\n      false,\n      [\"sign\"],\n    );\n    cryptoKeyCache.set(key, cryptoKey);\n  }\n\n  const signature = await subtle.sign(\n    \"HMAC\",\n    cryptoKey,\n    new TextEncoder().encode(encoded + ts),\n  );\n\n  return Array.from(new Uint8Array(signature))\n    .map((b) => b.toString(16).padStart(2, \"0\"))\n    .join(\"\");\n}\n\n/**\n * Sign data with a signing key using HMAC-SHA256.\n * Uses native crypto.subtle when available, falls back to hash.js.\n */\nexport async function signDataWithKey(\n  data: unknown,\n  signingKey: string,\n  ts: string,\n  logger: Logger,\n): Promise<string> {\n  const subtle = globalThis.crypto?.subtle;\n\n  logOnce(\n    logger,\n    \"debug\",\n    \"crypto-implementation\",\n    subtle\n      ? \"Using native Web Crypto for request signing\"\n      : \"Using hash.js fallback for request signing (native crypto unavailable)\",\n  );\n\n  if (subtle) {\n    try {\n      return await signWithNative(subtle, data, signingKey, ts);\n    } catch (err) {\n      logger.debug({ err }, \"Native crypto failed, falling back to hash.js\");\n    }\n  }\n  return signWithHashJs(data, signingKey, ts);\n}\n"],"mappings":";;;;;;;;;AAMA,MAAM,EAAE,MAAM,WAAWA;;;;;AAMzB,eAAsB,sBAAmD,EACvE,WACA,mBACA,OACA,SACA,OAOoB;CACpB,IAAI,MAAM,MAAM,MAAM,KAAK;EACzB,GAAG;EACH,SAAS;GACP,GAAG,SAAS;GACZ,eAAe,UAAU;GAC1B;EACF,CAAC;AAEF,KAAI,CAAC,KAAK,IAAI,CAAC,SAAS,IAAI,OAAO,IAAI,kBACrC,OAAM,MAAM,MAAM,KAAK;EACrB,GAAG;EACH,SAAS;GACP,GAAG,SAAS;GACZ,eAAe,UAAU;GAC1B;EACF,CAAC;AAGJ,QAAO;;AAGT,SAAgB,eACd,MACA,YACA,IACQ;CAKR,MAAM,UAAU,OAAO,SAAS,WAAW,iCAAoB,KAAK;AAOpE,QALY,KAAK,QAAeC,uCAAuB,WAAW,CAAC,CAChE,OAAO,QAAQ,CACf,OAAO,GAAG,CACV,OAAO,MAAM;;AAMlB,MAAM,iCAAiB,IAAI,KAAwB;AAEnD,eAAe,eACb,QACA,MACA,YACA,IACiB;CACjB,MAAM,UAAU,OAAO,SAAS,WAAW,iCAAoB,KAAK;CACpE,MAAM,MAAMA,uCAAuB,WAAW;CAE9C,IAAI,YAAY,eAAe,IAAI,IAAI;AACvC,KAAI,CAAC,WAAW;AACd,cAAY,MAAM,OAAO,UACvB,OACA,IAAI,aAAa,CAAC,OAAO,IAAI,EAC7B;GAAE,MAAM;GAAQ,MAAM;GAAW,EACjC,OACA,CAAC,OAAO,CACT;AACD,iBAAe,IAAI,KAAK,UAAU;;CAGpC,MAAM,YAAY,MAAM,OAAO,KAC7B,QACA,WACA,IAAI,aAAa,CAAC,OAAO,UAAU,GAAG,CACvC;AAED,QAAO,MAAM,KAAK,IAAI,WAAW,UAAU,CAAC,CACzC,KAAK,MAAM,EAAE,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAC3C,KAAK,GAAG;;;;;;AAOb,eAAsB,gBACpB,MACA,YACA,IACA,QACiB;CACjB,MAAM,SAAS,WAAW,QAAQ;AAElC,qBACE,QACA,SACA,yBACA,SACI,gDACA,yEACL;AAED,KAAI,OACF,KAAI;AACF,SAAO,MAAM,eAAe,QAAQ,MAAM,YAAY,GAAG;UAClD,KAAK;AACZ,SAAO,MAAM,EAAE,KAAK,EAAE,gDAAgD;;AAG1E,QAAO,eAAe,MAAM,YAAY,GAAG"}