{"version":3,"file":"internal.cjs","names":[],"sources":["../../src/utils/internal.ts"],"sourcesContent":["import type {\n  AccessToken,\n  IdTokenClaims,\n  Jwk,\n  MonoCloudUser,\n  SecurityAlgorithms,\n  JwsHeaderParameters,\n} from '../types';\n\n/**\n * @ignore\n * Converts a string to a Base64URL encoded string.\n *\n * @param input - The string to encode.\n *\n * @returns The Base64URL encoded string.\n */\nexport const toB64Url = (input: string): string =>\n  input.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n\n/**\n * @ignore\n * Parses a string value into a boolean.\n *\n * @param value - The string value to parse.\n *\n * @returns `true` if \"true\", `false` if \"false\", otherwise `undefined`.\n */\nexport const getBoolean = (value?: string): boolean | undefined => {\n  const v = value?.toLowerCase()?.trim();\n\n  if (v === 'true') {\n    return true;\n  }\n\n  if (v === 'false') {\n    return false;\n  }\n\n  return undefined;\n};\n\n/**\n * @ignore\n * Parses a string value into a number.\n *\n * @param value - The string value to parse.\n *\n * @returns The parsed number, or `undefined` if empty or invalid.\n */\nexport const getNumber = (value?: string): number | undefined => {\n  const v = value?.trim();\n\n  if (v === undefined || v.length === 0) {\n    return undefined;\n  }\n\n  const p = parseInt(v, 10);\n\n  return Number.isNaN(p) ? undefined : p;\n};\n\n/**\n * @ignore\n * Ensures that a string has a leading forward slash.\n *\n * @param val - The string to check.\n *\n * @returns The string with a leading slash.\n */\nexport const ensureLeadingSlash = (val?: string): string => {\n  const v = val?.trim();\n\n  if (!v) {\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    return v!;\n  }\n\n  return v.startsWith('/') ? v : `/${v}`;\n};\n\n/**\n * @ignore\n * Removes a trailing forward slash from a string.\n *\n * @param val - The string to check.\n *\n * @returns The string without a trailing slash.\n */\nexport const removeTrailingSlash = (val?: string): string => {\n  const v = val?.trim();\n\n  if (!v) {\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    return v!;\n  }\n\n  return v.endsWith('/') ? v.substring(0, v.length - 1) : v;\n};\n\n/**\n * @ignore\n * Checks if a value is present (not null, undefined, or an empty string).\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is present, `false` otherwise.\n */\nexport const isPresent = (\n  value?: string | number | boolean\n): value is string | number | boolean => {\n  if (typeof value === 'boolean' || typeof value === 'number') {\n    return true;\n  }\n  const v = value?.trim();\n  return v !== undefined && v !== null && v.length > 0;\n};\n\n/**\n * @ignore\n * Checks if a URL is an absolute URL (starts with http:// or https://).\n *\n * @param url - The URL to check.\n *\n * @returns `true` if absolute, `false` otherwise.\n */\nexport const isAbsoluteUrl = (url: string): boolean =>\n  (url?.startsWith('http://') || url?.startsWith('https://')) ?? false;\n\n/**\n * @ignore\n * Checks if two URLs have the same origin (host and port).\n *\n * @param url - The first URL.\n * @param urlToCheck - The second URL to compare against.\n *\n * @returns `true` if they share the same origin, `false` otherwise.\n */\nexport const isSameHost = (url: string, urlToCheck: string): boolean => {\n  try {\n    const u = new URL(url);\n    const u2 = new URL(urlToCheck);\n\n    return u.origin === u2.origin;\n  } catch {\n    return false;\n  }\n};\n\n/**\n * @ignore\n * Converts a string to a Uint8Array using TextEncoder.\n *\n * @param str - The string to convert.\n *\n * @returns A Uint8Array representation of the string.\n */\nexport const stringToArrayBuffer = (str: string): Uint8Array => {\n  const encoder = new TextEncoder();\n  return encoder.encode(str);\n};\n\n/**\n * @ignore\n * Converts an ArrayBuffer to a string using TextDecoder.\n *\n * @param buffer - The buffer to convert.\n *\n * @returns The decoded string.\n */\nexport const arrayBufferToString = (buffer: ArrayBuffer): string => {\n  const decoder = new TextDecoder();\n  return decoder.decode(buffer);\n};\n\n/**\n * @ignore\n * Encodes a string as standard (padded) Base64 from its UTF-8 bytes.\n *\n * @param input - The string to encode.\n *\n * @returns The Base64 encoded string.\n */\nexport const encodeBase64 = (input: string): string =>\n  btoa(\n    stringToArrayBuffer(input).reduce(\n      (acc, byte) => acc + String.fromCharCode(byte),\n      ''\n    )\n  );\n\n/**\n * @ignore\n * Compares two strings without leaking their contents through timing.\n *\n * @param a - The first string.\n * @param b - The second string.\n *\n * @returns `true` if the strings are equal.\n */\nexport const timingSafeEqual = (a: string, b: string): boolean => {\n  const aBytes = stringToArrayBuffer(a);\n  const bBytes = stringToArrayBuffer(b);\n\n  if (aBytes.length !== bBytes.length) {\n    return false;\n  }\n\n  let result = 0;\n\n  for (let i = 0; i < aBytes.length; i++) {\n    result |= aBytes[i] ^ bBytes[i];\n  }\n\n  return result === 0;\n};\n\n/**\n * @ignore\n * Converts a Base64URL string back to a standard Base64 string with padding.\n *\n * @param input - The Base64URL string.\n *\n * @returns A standard Base64 string.\n */\nexport const fromB64Url = (input: string): string => {\n  let str = input;\n  if (str.length % 4 !== 0) {\n    str += '==='.slice(0, 4 - (str.length % 4));\n  }\n\n  str = str.replace(/-/g, '+').replace(/_/g, '/');\n\n  return str;\n};\n\n/**\n * @ignore\n * Decodes a Base64URL encoded string.\n *\n * @param input - The Base64URL string to decode.\n *\n * @returns The decoded plaintext string.\n */\nexport const decodeBase64Url = (input: string): string =>\n  atob(fromB64Url(input).replace(/\\s/g, ''));\n\n/**\n * @ignore\n * Converts a Uint8Array to a Base64URL encoded string.\n *\n * @param buffer - The buffer to encode.\n *\n * @returns The Base64URL encoded string.\n */\nexport const arrayBufferToBase64 = (buffer: Uint8Array): string => {\n  const bytes = new Uint8Array(buffer);\n  const binary = bytes.reduce(\n    (acc, byte) => acc + String.fromCharCode(byte),\n    ''\n  );\n  return btoa(binary).replace(/=/g, '').replace(/\\+/g, '-').replace(/\\//g, '_');\n};\n\n/**\n * @ignore\n * Gets the current Unix timestamp in seconds.\n *\n * @returns The current timestamp.\n */\nexport const now = (): number => Math.floor(Date.now() / 1000);\n\nconst SUPPORTED_JWS_ALGS: SecurityAlgorithms[] = [\n  'RS256',\n  'RS384',\n  'RS512',\n  'PS256',\n  'PS384',\n  'PS512',\n  'ES256',\n  'ES384',\n  'ES512',\n];\n\n/**\n * Retrieves a public CryptoKey from a JWK set based on the JWS header.\n *\n * @param jwks - The set of JSON Web Keys.\n * @param header - The JWS header containing the algorithm and key ID.\n *\n * @returns A promise that resolves to the CryptoKey.\n *\n * @throws If no applicable key or multiple keys are found or the algorithm is unsupported.\n */\nexport const getPublicSigKeyFromIssuerJwks = async (\n  jwks: Jwk[],\n  header: JwsHeaderParameters\n): Promise<CryptoKey> => {\n  const { alg, kid } = header;\n\n  if (!SUPPORTED_JWS_ALGS.includes(alg)) {\n    throw new Error('unsupported JWS \"alg\" identifier');\n  }\n\n  let kty: string;\n  switch (alg.slice(0, 2)) {\n    case 'RS': // Fall through\n    case 'PS':\n      kty = 'RSA';\n      break;\n    case 'ES':\n      kty = 'EC';\n      break;\n  }\n\n  const candidates = jwks.filter(jwk => {\n    // filter keys based on the mapping of signature algorithms to Key Type\n    if (jwk.kty !== kty) {\n      return false;\n    }\n\n    // filter keys based on the JWK Key ID in the header\n    if (kid !== undefined && kid !== jwk.kid) {\n      return false;\n    }\n\n    // filter keys based on the key's declared Algorithm\n    if (jwk.alg !== undefined && alg !== jwk.alg) {\n      return false;\n    }\n\n    // filter keys based on the key's declared Public Key Use\n    if (jwk.use !== undefined && jwk.use !== 'sig') {\n      return false;\n    }\n\n    // filter keys based on the key's declared Key Operations\n    if (jwk.key_ops?.includes('verify') === false) {\n      return false;\n    }\n\n    // filter keys based on alg-specific key requirements\n    switch (true) {\n      case alg === 'ES256' && jwk.crv !== 'P-256': // Fall through\n      case alg === 'ES384' && jwk.crv !== 'P-384': // Fall through\n      case alg === 'ES512' && jwk.crv !== 'P-521': // Fall through\n        return false;\n    }\n\n    return true;\n  });\n\n  const { 0: jwk, length } = candidates;\n\n  if (length !== 1) {\n    throw new Error(\n      'error when selecting a JWT verification key, multiple applicable keys found, a \"kid\" JWT Header Parameter is required'\n    );\n  }\n\n  let algorithm:\n    RsaHashedImportParams | EcKeyImportParams | AlgorithmIdentifier;\n\n  switch (alg) {\n    case 'PS256': // Fall through\n    case 'PS384': // Fall through\n    case 'PS512':\n      algorithm = { name: 'RSA-PSS', hash: `SHA-${alg.slice(-3)}` };\n      break;\n    case 'RS256': // Fall through\n    case 'RS384': // Fall through\n    case 'RS512':\n      algorithm = { name: 'RSASSA-PKCS1-v1_5', hash: `SHA-${alg.slice(-3)}` };\n      break;\n    case 'ES256': // Fall through\n    case 'ES384':\n      algorithm = { name: 'ECDSA', namedCurve: `P-${alg.slice(-3)}` };\n      break;\n    case 'ES512':\n      algorithm = { name: 'ECDSA', namedCurve: 'P-521' };\n      break;\n  }\n\n  const { ext, key_ops, use, ...k } = jwk;\n\n  const key = await crypto.subtle.importKey('jwk', k, algorithm, true, [\n    'verify',\n  ]);\n\n  if (key.type !== 'public') {\n    throw new Error('jwks_uri must only contain public keys');\n  }\n\n  return key;\n};\n\nconst CHUNK_SIZE = 0x8000;\n\n/**\n * @ignore\n * Encodes a Uint8Array or ArrayBuffer into a Base64URL string using chunked processing.\n *\n * @param input - The data to encode.\n *\n * @returns The Base64URL encoded string.\n */\nexport const encodeBase64Url = (input: Uint8Array | ArrayBuffer): string => {\n  if (input instanceof ArrayBuffer) {\n    // eslint-disable-next-line no-param-reassign\n    input = new Uint8Array(input);\n  }\n\n  const arr = [];\n  for (let i = 0; i < input.byteLength; i += CHUNK_SIZE) {\n    arr.push(\n      String.fromCharCode.apply(\n        null,\n        Array.from(new Uint8Array(input.slice(i, i + CHUNK_SIZE)))\n      )\n    );\n  }\n  return btoa(arr.join(''))\n    .replace(/=/g, '')\n    .replace(/\\+/g, '-')\n    .replace(/\\//g, '_');\n};\n\n/**\n * @ignore\n * Computes a SHA-256 hash of the input string and returns it as a Base64URL encoded string.\n *\n * @param input - The string to hash.\n *\n * @returns The Base64URL encoded SHA-256 hash.\n */\nexport const sha256 = async (input: string): Promise<string> =>\n  encodeBase64Url(\n    await crypto.subtle.digest(\n      'SHA-256',\n      stringToArrayBuffer(input) as BufferSource\n    )\n  );\n\n/**\n * @ignore\n * Computes the base64url-encoded left-most half of the digest of `value`,\n * using the hash algorithm implied by an id token signing algorithm.\n *\n * @param value - The value to hash (for example an access token, code or state).\n * @param alg - The id token signing algorithm.\n *\n * @returns The base64url encoded left-most half of the digest.\n */\nexport const hashTokenValue = async (\n  value: string,\n  alg: SecurityAlgorithms\n): Promise<string> => {\n  const digest = `SHA-${alg.slice(-3)}`;\n\n  const hash = new Uint8Array(\n    await crypto.subtle.digest(\n      digest,\n      stringToArrayBuffer(value) as BufferSource\n    )\n  );\n\n  return encodeBase64Url(hash.slice(0, hash.length / 2));\n};\n\n/**\n * @ignore\n * Validates an OpenID Connect hash claim (such as `at_hash`, `c_hash` or\n * `s_hash`) against the value it was derived from.\n *\n * @param value - The value the hash was derived from (for example the access token or state).\n * @param expectedHash - The hash claim value present in the id token.\n * @param alg - The id token signing algorithm.\n *\n * @returns `true` when the computed hash matches `expectedHash`, `false` otherwise.\n */\nexport const validateTokenHash = async (\n  value: string,\n  expectedHash: string,\n  alg: SecurityAlgorithms\n): Promise<boolean> =>\n  timingSafeEqual(await hashTokenValue(value, alg), expectedHash);\n\n/**\n * @ignore\n * Generates a random Base64URL encoded string.\n *\n * @param length - The number of random bytes to generate.\n *\n * @returns A random Base64URL string.\n */\nexport const randomBytes = (length = 32): string =>\n  encodeBase64Url(crypto.getRandomValues(new Uint8Array(length)));\n\n/**\n * @ignore\n * Checks if a value is a non-null, non-array JSON object.\n *\n * @param input - The value to check.\n *\n * @returns `true` if the value is a JSON object.\n */\nexport const isJsonObject = <T>(input: unknown): input is T => {\n  if (input === null || typeof input !== 'object' || Array.isArray(input)) {\n    return false;\n  }\n\n  return true;\n};\n\n/**\n * @ignore\n * Resolves a client secret supplied as a string.\n *\n * When the string parses to a JWK — a JSON object with a string `kty` member, such as the\n * private key used with the `private_key_jwt` client authentication method — the parsed object\n * is returned. Any other value (a plain-text secret, non-JWK JSON, or a value already provided\n * as an object) is returned unchanged.\n *\n * @param value - The raw client secret (a string, a JWK object, or `undefined`).\n *\n * @returns The parsed JWK object, the original string secret, or `undefined`.\n */\nexport const parseClientSecret = (\n  value?: string | Jwk\n): string | Jwk | undefined => {\n  if (typeof value !== 'string') {\n    return value;\n  }\n\n  try {\n    const parsed: unknown = JSON.parse(value);\n    if (\n      typeof parsed === 'object' &&\n      parsed !== null &&\n      typeof (parsed as Record<string, unknown>).kty === 'string'\n    ) {\n      return parsed as Jwk;\n    }\n  } catch {\n    // Not JSON — fall through and treat the value as a plain-text secret.\n  }\n\n  return value;\n};\n\n/**\n * @ignore\n * Parses a space-separated string into an array of strings.\n *\n * @param s - The space-separated string.\n *\n * @returns An array of strings, or `undefined` if input is empty.\n */\nexport const parseSpaceSeparated = (s?: string): string[] | undefined =>\n  s\n    ?.split(/\\s+/)\n    .map(x => x.trim())\n    .filter(Boolean);\n\n/**\n * @ignore\n * Parses a space-separated string into a Set of strings.\n *\n * @param s - The space-separated string.\n *\n * @returns A Set containing the unique strings.\n */\nexport const parseSpaceSeparatedSet = (s?: string): Set<string> => {\n  if (!s) {\n    return new Set();\n  }\n\n  return new Set(parseSpaceSeparated(s));\n};\n\n/**\n * @ignore\n * Compares two Sets for equality.\n *\n * @param a - The first Set.\n * @param b - The second Set.\n * @param strict - If `true`, requires both sets to be the same size. Defaults to `true`.\n *\n * @returns `true` if the sets are equal.\n */\nexport const setsEqual = (\n  a: Set<string>,\n  b: Set<string>,\n  strict = true\n): boolean => {\n  if (strict && a.size !== b.size) {\n    return false;\n  }\n\n  for (const v of a) {\n    if (!b.has(v)) {\n      return false;\n    }\n  }\n\n  return true;\n};\n\n/**\n * Finds a specific access token in an array based on resource and scopes.\n *\n * @param tokens - The array of access tokens.\n * @param resource - Space-separated resource indicators.\n * @param scopes - Space-separated scopes.\n *\n * @returns The matching AccessToken, or `undefined` if not found.\n */\nexport const findToken = (\n  tokens?: AccessToken[],\n  resource?: string,\n  scopes?: string\n): AccessToken | undefined => {\n  if (!Array.isArray(tokens) || tokens.length === 0) {\n    return undefined;\n  }\n\n  const desiredResource = parseSpaceSeparatedSet(resource);\n  const desiredScopes = parseSpaceSeparatedSet(scopes);\n\n  return tokens.find(\n    t =>\n      setsEqual(desiredResource, parseSpaceSeparatedSet(t.resource)) &&\n      setsEqual(desiredScopes, parseSpaceSeparatedSet(t.requestedScopes))\n  );\n};\n\n/**\n * @ignore\n * Builds the session user claims from existing claims and newly fetched claims.\n *\n * @param existingUser - Existing session user claims.\n * @param idTokenClaims - Claims extracted from ID token.\n * @param userinfoClaims - Claims fetched from UserInfo endpoint.\n * @param strict - If `true`, creates claims from new inputs only (falls back to existing when none). If `false`, merges into existing claims.\n *\n * @returns Updated user claims for the session.\n */\nexport const profileSync = (\n  existingUser?: MonoCloudUser,\n  idTokenClaims?: Partial<IdTokenClaims>,\n  userinfoClaims?: Partial<MonoCloudUser>,\n  strict = false\n): MonoCloudUser => {\n  const hasIdTokenClaims =\n    !!idTokenClaims && Object.keys(idTokenClaims).length > 0;\n  const hasUserinfoClaims =\n    !!userinfoClaims && Object.keys(userinfoClaims).length > 0;\n\n  if (!hasIdTokenClaims && !hasUserinfoClaims) {\n    return existingUser ?? ({} as MonoCloudUser);\n  }\n\n  if (strict) {\n    return {\n      ...(idTokenClaims ?? {}),\n      ...(userinfoClaims ?? {}),\n    } as MonoCloudUser;\n  }\n\n  return {\n    ...(existingUser ?? {}),\n    ...(idTokenClaims ?? {}),\n    ...(userinfoClaims ?? {}),\n  } as MonoCloudUser;\n};\n"],"mappings":"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"}