{"version":3,"file":"cache.mjs","sourceRoot":"","sources":["../../../src/shared/encryption/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,wBAAoB;AAC1C,OAAO,EAAE,iBAAiB,EAAE,oBAAgB;AAQ5C,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAChC,MAAM,eAAe,GAAG,GAAG,CAAC;AAQ5B,IAAI,cAAc,GAAyB,EAAE,CAAC;AAC9C,MAAM,gBAAgB,GAAG,CAAC,cAAsB,EAAE,EAAE;IAClD,cAAc,CAAC,cAAc,MAA7B,cAAc,CAAC,cAAc,IAAM,IAAI,GAAG,EAAE,EAAC;IAC7C,OAAO,cAAc,CAAC,cAAc,CAAC,CAAC;AACxC,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAChC,cAAsB,EACtB,IAAgB;IAEhB,MAAM,KAAK,GAAG,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAC/C,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACxC,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO;QACL,IAAI;QACJ,UAAU;QACV,GAAG,EAAE,SAAS;KACf,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mCAAmC,CACjD,cAAsB;IAEtB,MAAM,KAAK,GAAG,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAC/C,MAAM,UAAU,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAExC,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO;QACL,IAAI,EAAE,WAAW;QACjB,UAAU;QACV,GAAG,EAAE,SAAS;KACf,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAC1B,cAAsB,EACtB,IAAgB,EAChB,GAAe;IAEf,sBAAsB;IACtB,IAAI,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,MAAM,GAAG,mBAAmB,EAAE,CAAC;QAC7D,cAAc,GAAG,EAAE,CAAC;IACtB,CAAC;IAED,MAAM,KAAK,GAAG,gBAAgB,CAAC,cAAc,CAAC,CAAC;IAC/C,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAE3C,kBAAkB;IAClB,IAAI,KAAK,CAAC,IAAI,GAAG,eAAe,EAAE,CAAC;QACjC,KAAK,CAAC,KAAK,EAAE,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;AAC7B,CAAC","sourcesContent":["import { SHARED_SALT } from './constants';\nimport { byteArrayToBase64 } from './utils';\n\ntype CachedEntry = {\n  salt: Uint8Array;\n  base64Salt: string;\n  key: Uint8Array;\n};\n\nconst MAX_PASSWORD_CACHES = 100;\nconst MAX_SALT_CACHES = 100;\n\n/**\n * In-Memory Caching derived keys based from a given salt and password.\n */\ntype PasswordMemCachedKDF = {\n  [hashedPassword: string]: Map<string, Uint8Array>;\n};\nlet inMemCachedKDF: PasswordMemCachedKDF = {};\nconst getPasswordCache = (hashedPassword: string) => {\n  inMemCachedKDF[hashedPassword] ??= new Map();\n  return inMemCachedKDF[hashedPassword];\n};\n\n/**\n * Returns a given cached derived key from a hashed password and salt\n *\n * @param hashedPassword - hashed password for cache lookup\n * @param salt - provide salt to receive cached key\n * @returns cached key\n */\nexport function getCachedKeyBySalt(\n  hashedPassword: string,\n  salt: Uint8Array,\n): CachedEntry | undefined {\n  const cache = getPasswordCache(hashedPassword);\n  const base64Salt = byteArrayToBase64(salt);\n  const cachedKey = cache.get(base64Salt);\n  if (!cachedKey) {\n    return undefined;\n  }\n\n  return {\n    salt,\n    base64Salt,\n    key: cachedKey,\n  };\n}\n\n/**\n * Gets the cached key that was generated without a salt, if it exists.\n * This is unique per hashed password.\n *\n * @param hashedPassword - hashed password for cache lookup\n * @returns the cached key\n */\nexport function getCachedKeyGeneratedWithSharedSalt(\n  hashedPassword: string,\n): CachedEntry | undefined {\n  const cache = getPasswordCache(hashedPassword);\n  const base64Salt = byteArrayToBase64(SHARED_SALT);\n  const cachedKey = cache.get(base64Salt);\n\n  if (!cachedKey) {\n    return undefined;\n  }\n\n  return {\n    salt: SHARED_SALT,\n    base64Salt,\n    key: cachedKey,\n  };\n}\n\n/**\n * Sets a key to the in memory cache.\n * We have set an arbitrary size of 10 cached keys per hashed password.\n *\n * @param hashedPassword - hashed password for cache lookup\n * @param salt - salt to set new derived key\n * @param key - derived key we are setting\n */\nexport function setCachedKey(\n  hashedPassword: string,\n  salt: Uint8Array,\n  key: Uint8Array,\n): void {\n  // Max password caches\n  if (Object.keys(inMemCachedKDF).length > MAX_PASSWORD_CACHES) {\n    inMemCachedKDF = {};\n  }\n\n  const cache = getPasswordCache(hashedPassword);\n  const base64Salt = byteArrayToBase64(salt);\n\n  // Max salt caches\n  if (cache.size > MAX_SALT_CACHES) {\n    cache.clear();\n  }\n\n  cache.set(base64Salt, key);\n}\n"]}