#!/usr/bin/env node
/******/ (() => { // webpackBootstrap
/******/ 	"use strict";
/******/ 	var __webpack_modules__ = ({

/***/ 330
(module) {

module.exports = /*#__PURE__*/JSON.parse('{"name":"@bitwarden/cli","description":"A secure and free password manager for all of your devices.","version":"2026.4.2","keywords":["bitwarden","password","vault","password manager","cli"],"author":"Bitwarden Inc. <hello@bitwarden.com> (https://bitwarden.com)","homepage":"https://bitwarden.com","repository":{"type":"git","url":"git+https://github.com/bitwarden/clients.git"},"license":"SEE LICENSE IN LICENSE.txt","scripts":{"clean":"rimraf dist","build:oss":"webpack","build:oss:debug":"npm run build:oss && node --inspect ./build/bw.js","build:oss:watch":"webpack --watch","build:oss:prod":"cross-env NODE_ENV=production webpack","build:oss:prod:watch":"cross-env NODE_ENV=production webpack --watch","debug":"node --inspect ./build/bw.js","publish:npm":"npm run build:oss:prod && npm publish --access public","build:bit":"webpack -c ../../bitwarden_license/bit-cli/webpack.config.js","build:bit:debug":"npm run build:bit && node --inspect ./build/bw.js","build:bit:watch":"webpack --watch -c ../../bitwarden_license/bit-cli/webpack.config.js","build:bit:prod":"cross-env NODE_ENV=production npm run build:bit","build:bit:prod:watch":"cross-env NODE_ENV=production npm run build:bit:watch","dist:oss:win":"npm run build:oss:prod && npm run clean && npm run package:oss:win","dist:oss:mac":"npm run build:oss:prod && npm run clean && npm run package:oss:mac","dist:oss:mac-arm64":"npm run build:oss:prod && npm run clean && npm run package:oss:mac-arm64","dist:oss:lin":"npm run build:oss:prod && npm run clean && npm run package:oss:lin","dist:oss:lin-arm64":"npm run build:oss:prod && npm run clean && npm run package:oss:lin-arm64","dist:bit:win":"npm run build:bit:prod && npm run clean && npm run package:bit:win","dist:bit:mac":"npm run build:bit:prod && npm run clean && npm run package:bit:mac","dist:bit:mac-arm64":"npm run build:bit:prod && npm run clean && npm run package:bit:mac-arm64","dist:bit:lin":"npm run build:bit:prod && npm run clean && npm run package:bit:lin","dist:bit:lin-arm64":"npm run build:bit:prod && npm run clean && npm run package:bit:lin-arm64","package:oss:win":"pkg . --targets win-x64 --output ./dist/oss/windows/bw.exe","package:oss:mac":"pkg . --targets macos-x64 --output ./dist/oss/macos/bw","package:oss:mac-arm64":"pkg . --targets macos-arm64 --output ./dist/oss/macos-arm64/bw","package:oss:lin":"pkg . --targets linux-x64 --output ./dist/oss/linux/bw","package:oss:lin-arm64":"pkg . --targets linux-arm64 --output ./dist/oss/linux-arm64/bw","package:bit:win":"pkg . --targets win-x64 --output ./dist/bit/windows/bw.exe","package:bit:mac":"pkg . --targets macos-x64 --output ./dist/bit/macos/bw","package:bit:mac-arm64":"pkg . --targets macos-arm64 --output ./dist/bit/macos-arm64/bw","package:bit:lin":"pkg . --targets linux-x64 --output ./dist/bit/linux/bw","package:bit:lin-arm64":"pkg . --targets linux-arm64 --output ./dist/bit/linux-arm64/bw","test":"jest","test:watch":"jest --watch","test:watch:all":"jest --watchAll"},"bin":{"bw":"build/bw.js"},"pkg":{"assets":["./build/**/*"]},"dependencies":{"@koa/multer":"4.0.0","@koa/router":"15.4.0","big-integer":"1.6.52","browser-hrtime":"1.1.8","chalk":"4.1.2","commander":"14.0.0","core-js":"3.48.0","form-data":"4.0.4","https-proxy-agent":"7.0.6","inquirer":"8.2.6","jsdom":"26.1.0","jszip":"3.10.1","koa":"3.1.2","koa-bodyparser":"4.4.1","koa-json":"2.0.2","lowdb":"1.0.0","lunr":"2.3.9","multer":"2.1.1","node-fetch":"2.7.0","node-forge":"1.3.2","open":"8.4.2","papaparse":"5.5.3","proper-lockfile":"4.1.2","rxjs":"7.8.1","semver":"7.7.3","tldts":"7.0.22","zxcvbn":"4.4.2"}}');

/***/ },

/***/ 431
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {

/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   $1F: () => (/* binding */ __wbg_instanceof_IdbRequest_6a0e24572d4f1d46),
/* harmony export */   $85: () => (/* binding */ __wbg_resolve_ae8d83246e5bcc12),
/* harmony export */   $Au: () => (/* binding */ __wbg_removeBulk_ac338f90b239797d),
/* harmony export */   $Uo: () => (/* binding */ __wbindgen_cast_000000000000000a),
/* harmony export */   $bb: () => (/* binding */ LogLevel),
/* harmony export */   $g3: () => (/* binding */ __wbg_set_headers_3c8fecc693b75327),
/* harmony export */   $iT: () => (/* binding */ __wbg_append_608dfb635ee8998f),
/* harmony export */   $uP: () => (/* binding */ __wbg_local_user_data_key_state_a42fa6c432ab2a9e),
/* harmony export */   AIg: () => (/* binding */ __wbg_list_7a28414a08b60036),
/* harmony export */   ANT: () => (/* binding */ __wbg_mark_310e9a031ccc84ff),
/* harmony export */   Ac_: () => (/* binding */ __wbg_get_9558fffcf2da2e5d),
/* harmony export */   B8s: () => (/* binding */ __wbg___wbindgen_jsval_eq_ee31bfad3e536463),
/* harmony export */   BHc: () => (/* binding */ __wbg_append_bbf73d7e78ce268c),
/* harmony export */   BZb: () => (/* binding */ __wbindgen_object_clone_ref),
/* harmony export */   Bn3: () => (/* binding */ __wbg_setBulk_65ae23b49b7055f4),
/* harmony export */   CnV: () => (/* binding */ __wbg_new_0_1dcafdf5e786e876),
/* harmony export */   CqO: () => (/* binding */ __wbg_remove_433cff70ed894243),
/* harmony export */   D4x: () => (/* binding */ __wbg_debug_271c16e6de0bc226),
/* harmony export */   D6r: () => (/* binding */ __wbg___wbindgen_string_get_395e606bd0ee4427),
/* harmony export */   D85: () => (/* binding */ __wbg_removeAll_e37dca02c04bad64),
/* harmony export */   DL0: () => (/* binding */ __wbg_error_a6fa202b58aa1cd3),
/* harmony export */   DMn: () => (/* binding */ __wbg_error_1eece6b0039034ce),
/* harmony export */   DOu: () => (/* binding */ __wbg_static_accessor_GLOBAL_8adb955bd33fac2f),
/* harmony export */   Dbn: () => (/* binding */ __wbg_value_21fc78aab0322612),
/* harmony export */   DxH: () => (/* binding */ __wbg_iterator_d8f549ec8fb061b1),
/* harmony export */   E5T: () => (/* binding */ __wbg_put_f1673d719f93ce22),
/* harmony export */   E9s: () => (/* binding */ __wbg_measure_54743279e77e77bb),
/* harmony export */   EMz: () => (/* binding */ __wbg_getRandomValues_ef12552bf5acd2fe),
/* harmony export */   Ek9: () => (/* binding */ __wbg_removeAll_83d9b879edf3edf5),
/* harmony export */   FjX: () => (/* binding */ __wbg_stringify_5ae93966a84901ac),
/* harmony export */   FmJ: () => (/* binding */ __wbg_list_92ac9ca899e49952),
/* harmony export */   Fxm: () => (/* binding */ __wbg_removeBulk_1b4de37c14766bfc),
/* harmony export */   G0e: () => (/* binding */ __wbindgen_cast_0000000000000008),
/* harmony export */   GE9: () => (/* binding */ __wbg_text_372f5b91442c50f9),
/* harmony export */   Geh: () => (/* binding */ init_sdk),
/* harmony export */   Gg9: () => (/* binding */ __wbg_String_8564e559799eccda),
/* harmony export */   Gjz: () => (/* binding */ __wbg_new_with_u8_array_sequence_and_options_de38f663e19ad899),
/* harmony export */   Gu3: () => (/* binding */ __wbg_save_68ac7f7c3c522f0f),
/* harmony export */   HQp: () => (/* binding */ __wbg_call_e133b57c9155d22c),
/* harmony export */   HoS: () => (/* binding */ __wbg_queueMicrotask_0c399741342fb10f),
/* harmony export */   Hrx: () => (/* binding */ __wbg_set_f35d433431c47d2f),
/* harmony export */   HvI: () => (/* binding */ __wbg_ipcclientsubscription_new),
/* harmony export */   IAB: () => (/* binding */ __wbg_get_with_ref_key_6412cf3094599694),
/* harmony export */   ID_: () => (/* binding */ __wbg_get_2ccd8acbf5c86922),
/* harmony export */   IEs: () => (/* binding */ PureCrypto),
/* harmony export */   IF6: () => (/* binding */ __wbg_new_with_str_and_init_b4b54d1a819bc724),
/* harmony export */   IRJ: () => (/* binding */ __wbg_getTime_1dad7b5386ddd2d9),
/* harmony export */   IZ7: () => (/* binding */ __wbg_entries_e8a20ff8c9757101),
/* harmony export */   Ib0: () => (/* binding */ __wbg_error_74898554122344a8),
/* harmony export */   JCT: () => (/* binding */ __wbg_set_variant_8b1ee86f2f7d9515),
/* harmony export */   JLl: () => (/* binding */ __wbg_get_bc1924700555f403),
/* harmony export */   JdB: () => (/* binding */ __wbg_url_7fefc1820fba4e0c),
/* harmony export */   Jzh: () => (/* binding */ __wbg_remove_6dd84ec06dcd438d),
/* harmony export */   K83: () => (/* binding */ __wbg_organization_shared_key_eff6fc3c86be0319),
/* harmony export */   KE4: () => (/* binding */ __wbg_get_ab6398926dce696f),
/* harmony export */   KiH: () => (/* binding */ __wbg_get_unchecked_329cfe50afab7352),
/* harmony export */   KoG: () => (/* binding */ __wbg_removeBulk_452b7a89d11d0694),
/* harmony export */   Kqd: () => (/* binding */ __wbg_get_326e41e095fb2575),
/* harmony export */   Kyl: () => (/* binding */ __wbg__wbg_cb_unref_6b5b6b8576d35cb1),
/* harmony export */   L1u: () => (/* binding */ __wbg_get_1a199cb285f5075b),
/* harmony export */   L9h: () => (/* binding */ __wbg_static_accessor_GLOBAL_THIS_ad356e0db91c7913),
/* harmony export */   Lju: () => (/* binding */ __wbg_setTimeout_f757f00851f76c42),
/* harmony export */   LlB: () => (/* binding */ __wbg_isArray_33b91feb269ff46e),
/* harmony export */   MB3: () => (/* binding */ __wbg_new_49d5571bd3f0c4d4),
/* harmony export */   MB6: () => (/* binding */ __wbg_append_83e47d4b428d97aa),
/* harmony export */   Mc5: () => (/* binding */ __wbg_target_7bc90f314634b37b),
/* harmony export */   N93: () => (/* binding */ __wbg_append_48b3d4fc4c97ab8d),
/* harmony export */   NAj: () => (/* binding */ __wbg_get_3ef1eba1850ade27),
/* harmony export */   NCs: () => (/* binding */ __wbindgen_cast_0000000000000007),
/* harmony export */   NRA: () => (/* binding */ __wbindgen_cast_0000000000000001),
/* harmony export */   NX2: () => (/* binding */ __wbg_getAll_690f659b57ae2d51),
/* harmony export */   Ney: () => (/* binding */ __wbg_new_with_length_3259a525196bd8cc),
/* harmony export */   Nm_: () => (/* binding */ __wbg_mark_742962d66a858cc5),
/* harmony export */   Nz0: () => (/* binding */ __wbg_queueMicrotask_a082d78ce798393e),
/* harmony export */   OrY: () => (/* binding */ __wbg_set_d13ca84b8469dec0),
/* harmony export */   PC6: () => (/* binding */ __wbg_debug_4b9b1a2d5972be57),
/* harmony export */   PUO: () => (/* binding */ FieldType),
/* harmony export */   PUW: () => (/* binding */ __wbindgen_cast_0000000000000005),
/* harmony export */   Pcj: () => (/* binding */ __wbg_set_cache_ec7e430c6056ebda),
/* harmony export */   QWb: () => (/* binding */ __wbg_fetch_9dad4fe911207b37),
/* harmony export */   RKI: () => (/* binding */ __wbg_isSafeInteger_ecd6a7f9c3e053cd),
/* harmony export */   Rr9: () => (/* binding */ __wbg_instanceof_Map_f194b366846aca0c),
/* harmony export */   Rzd: () => (/* binding */ __wbg_name_7a3bbd030d0afa16),
/* harmony export */   S2f: () => (/* binding */ __wbg_removeBulk_e18ea7127397fa26),
/* harmony export */   SQ0: () => (/* binding */ __wbg_instanceof_ArrayBuffer_101e2bf31071a9f6),
/* harmony export */   SWp: () => (/* binding */ __wbg_new_ab79df5bd7c26067),
/* harmony export */   St$: () => (/* binding */ __wbg_incomingmessage_new),
/* harmony export */   Tu9: () => (/* binding */ __wbg_getRandomValues_76dfc69825c9c552),
/* harmony export */   U53: () => (/* binding */ __wbg_Error_83742b46f01ce22d),
/* harmony export */   UEv: () => (/* binding */ __wbg___wbindgen_is_string_7ef6b97b02428fae),
/* harmony export */   ULw: () => (/* binding */ __wbg_set_type_33e79f1b45a78c37),
/* harmony export */   U_B: () => (/* binding */ __wbindgen_cast_0000000000000002),
/* harmony export */   UeG: () => (/* binding */ __wbindgen_cast_0000000000000006),
/* harmony export */   Ugb: () => (/* binding */ __wbindgen_cast_000000000000000b),
/* harmony export */   VG1: () => (/* binding */ __wbg_new_c518c60af666645b),
/* harmony export */   VWO: () => (/* binding */ __wbg___wbindgen_is_bigint_e2141d4f045b7eda),
/* harmony export */   Vki: () => (/* binding */ __wbg_abort_6479c2d794ebf2ee),
/* harmony export */   Vqp: () => (/* binding */ __wbg_set_onsuccess_fca94ded107b64af),
/* harmony export */   WIM: () => (/* binding */ __wbg_set_11072e94887ebb20),
/* harmony export */   WRv: () => (/* binding */ __wbg_setBulk_e7f56f73e97d6782),
/* harmony export */   Wh6: () => (/* binding */ __wbg_warn_809cad1bfc2b3a42),
/* harmony export */   Wkq: () => (/* binding */ __wbg_cipher_3d45684f136684e7),
/* harmony export */   Ww_: () => (/* binding */ __wbindgen_cast_0000000000000004),
/* harmony export */   XHY: () => (/* binding */ __wbg_addEventListener_14aecf4b28f9db02),
/* harmony export */   XQO: () => (/* binding */ __wbg_user_key_state_716a6e0f86936052),
/* harmony export */   X_E: () => (/* binding */ __wbg___wbindgen_boolean_get_c0f3f60bac5a78d1),
/* harmony export */   XpY: () => (/* binding */ __wbindgen_cast_0000000000000010),
/* harmony export */   Xtx: () => (/* binding */ __wbg_setBulk_19a0b37f4955b796),
/* harmony export */   YH6: () => (/* binding */ __wbg_set_name_1a2f99370b3248bd),
/* harmony export */   YIv: () => (/* binding */ __wbg___wbindgen_throw_6ddd609b62940d55),
/* harmony export */   Yb$: () => (/* binding */ __wbg_new_2d996564533475e2),
/* harmony export */   Ykw: () => (/* binding */ __wbg_set_mode_5a87f2c809cf37c2),
/* harmony export */   Ylw: () => (/* binding */ __wbg_removeAll_d2bf38f9bc9aea1f),
/* harmony export */   YrG: () => (/* binding */ __wbg___wbindgen_jsval_loose_eq_5bcc3bed3c69e72b),
/* harmony export */   _P4: () => (/* binding */ __wbg_info_7d4e223bb1a7e671),
/* harmony export */   _Rr: () => (/* binding */ __wbg___wbindgen_is_object_781bc9f159099513),
/* harmony export */   _WK: () => (/* binding */ __wbg_Number_a5a435bd7bbec835),
/* harmony export */   _xL: () => (/* binding */ __wbg___wbindgen_debug_string_5398f5bb970e0daa),
/* harmony export */   a5G: () => (/* binding */ __wbg_send_bc57e3d44b1ae6d7),
/* harmony export */   aLo: () => (/* binding */ __wbg_call_2d781c1f4d5c0ef8),
/* harmony export */   acE: () => (/* binding */ __wbg_measure_cd1f7667d5f5517d),
/* harmony export */   b$l: () => (/* binding */ __wbindgen_cast_0000000000000003),
/* harmony export */   b3E: () => (/* binding */ __wbg_set_signal_0cebecb698f25d21),
/* harmony export */   b90: () => (/* binding */ __wbg_stack_3b0d974bbf31e44f),
/* harmony export */   bAX: () => (/* binding */ __wbg_remove_6a2ee8e510094e40),
/* harmony export */   bRe: () => (/* binding */ __wbg_new_d15cb560a6a0e5f0),
/* harmony export */   bWd: () => (/* binding */ __wbindgen_cast_0000000000000009),
/* harmony export */   bYK: () => (/* binding */ __wbindgen_cast_000000000000000e),
/* harmony export */   bkt: () => (/* binding */ __wbindgen_object_drop_ref),
/* harmony export */   bnN: () => (/* binding */ import_ssh_key),
/* harmony export */   cH4: () => (/* binding */ __wbg_error_8d9a8e04cd1d3588),
/* harmony export */   cKH: () => (/* binding */ __wbg_set_7eaa4f96924fd6b3),
/* harmony export */   cPU: () => (/* binding */ PasswordManagerClient),
/* harmony export */   cmn: () => (/* binding */ __wbg_set_282384002438957f),
/* harmony export */   d5N: () => (/* binding */ __wbg_setBulk_11b4b57960e030a6),
/* harmony export */   dBT: () => (/* binding */ __wbg_remove_36a0891eeaffb08e),
/* harmony export */   dHr: () => (/* binding */ __wbg_set_9079c80d0e4cae97),
/* harmony export */   dNJ: () => (/* binding */ __wbg_transaction_3223f7c8d0f40129),
/* harmony export */   dPP: () => (/* binding */ __wbg_set_onerror_8a268cb237177bba),
/* harmony export */   d_3: () => (/* binding */ __wbg_instanceof_DomException_2bdcf7791a2d7d09),
/* harmony export */   eGc: () => (/* binding */ __wbg_get_ec32bde1b0c823cc),
/* harmony export */   eeG: () => (/* binding */ __wbg_acquireCookies_6c408397b3a34df5),
/* harmony export */   etH: () => (/* binding */ __wbg_set_107d6f53da51edcf),
/* harmony export */   eu7: () => (/* binding */ __wbg___wbindgen_is_function_3c846841762788c1),
/* harmony export */   f3S: () => (/* binding */ __wbg_list_2f90f406548f9445),
/* harmony export */   fRR: () => (/* binding */ __wbg_setBulk_eb51976bf9f6732d),
/* harmony export */   faj: () => (/* binding */ __wbg_ephemeral_pin_envelope_state_a57f8d9c123d28c6),
/* harmony export */   fes: () => (/* binding */ __wbg_folder_0b01534304da4704),
/* harmony export */   fgh: () => (/* binding */ __wbg_static_accessor_performance_da77b3a901a72934),
/* harmony export */   giu: () => (/* binding */ __wbindgen_cast_000000000000000f),
/* harmony export */   gkX: () => (/* binding */ isCryptoError),
/* harmony export */   gsc: () => (/* binding */ __wbg_setBulk_24eb76b34ac7d59a),
/* harmony export */   hVt: () => (/* binding */ __wbg_set_credentials_ed63183445882c65),
/* harmony export */   hjS: () => (/* binding */ __wbg_new_a70fbab9066b301f),
/* harmony export */   iAY: () => (/* binding */ __wbindgen_cast_000000000000000d),
/* harmony export */   iEd: () => (/* binding */ __wbg_static_accessor_WINDOW_bb9f1ba69d61b386),
/* harmony export */   inY: () => (/* binding */ __wbg_remove_11c0c0ad23369948),
/* harmony export */   irN: () => (/* binding */ __wbg_preventDefault_25a229bfe5c510f8),
/* harmony export */   jXz: () => (/* binding */ __wbg_getFullYear_f6d84c054eee1543),
/* harmony export */   jY2: () => (/* binding */ __wbg_get_a8ee5c45dabc1b3b),
/* harmony export */   joy: () => (/* binding */ __wbg_status_318629ab93a22955),
/* harmony export */   kMP: () => (/* binding */ __wbg___wbindgen_is_null_0b605fc6b167c56f),
/* harmony export */   kSo: () => (/* binding */ __wbg_then_098abe61755d12f6),
/* harmony export */   ko8: () => (/* binding */ __wbg_length_b3416cf66a5452c8),
/* harmony export */   lIU: () => (/* binding */ __wbg_set_wasm),
/* harmony export */   lUx: () => (/* binding */ __wbg_has_926ef2ff40b308cf),
/* harmony export */   lcU: () => (/* binding */ __wbg_push_e87b0e732085a946),
/* harmony export */   ljp: () => (/* binding */ __wbg_clearTimeout_6b8d9a38b9263d65),
/* harmony export */   lsE: () => (/* binding */ __wbg_set_bf7251625df30a02),
/* harmony export */   lw9: () => (/* binding */ __wbg_abort_5ef96933660780b7),
/* harmony export */   mXs: () => (/* binding */ __wbg_new_227d7c05414eb861),
/* harmony export */   mjc: () => (/* binding */ __wbg_removeAll_021cbeb363328530),
/* harmony export */   muV: () => (/* binding */ __wbg_new_from_slice_22da9388ac046e50),
/* harmony export */   my: () => (/* binding */ __wbg_signal_166e1da31adcac18),
/* harmony export */   nR2: () => (/* binding */ __wbg_arrayBuffer_eb8e9ca620af2a19),
/* harmony export */   nZ: () => (/* binding */ __wbg_result_c5baa2d3d690a01a),
/* harmony export */   niZ: () => (/* binding */ __wbg_get_access_token_b777a991688c2b49),
/* harmony export */   nq3: () => (/* binding */ __wbg_static_accessor_SELF_f207c857566db248),
/* harmony export */   nuP: () => (/* binding */ __wbg_set_48a8c36e440ef4d7),
/* harmony export */   o1H: () => (/* binding */ __wbg_new_0837727332ac86ba),
/* harmony export */   oZC: () => (/* binding */ __wbg_fetch_5550a88cf343aaa9),
/* harmony export */   ol7: () => (/* binding */ __wbg_prototypesetcall_d62e5099504357e6),
/* harmony export */   pPt: () => (/* binding */ __wbg___wbindgen_bigint_get_as_i64_447a76b5c6ef7bda),
/* harmony export */   pQh: () => (/* binding */ __wbg_set_6be42768c690e380),
/* harmony export */   pUe: () => (/* binding */ __wbg_get_6ac8c8119f577720),
/* harmony export */   pc: () => (/* binding */ __wbindgen_cast_000000000000000c),
/* harmony export */   pkv: () => (/* binding */ __wbg_info_0194681687b5ab04),
/* harmony export */   pql: () => (/* binding */ __wbg_new_5cfc6a14488ab25a),
/* harmony export */   qXY: () => (/* binding */ __wbg_removeAll_30b3939f3f5c8bdf),
/* harmony export */   qpf: () => (/* binding */ __wbg_removeBulk_e55dcd29d10ae184),
/* harmony export */   r3k: () => (/* binding */ __wbg_instanceof_Uint8Array_740438561a5b956d),
/* harmony export */   r5P: () => (/* binding */ __wbg_removeAll_f058d82b1aa15ca5),
/* harmony export */   rU4: () => (/* binding */ __wbg_headers_eb2234545f9ff993),
/* harmony export */   sIo: () => (/* binding */ __wbg_length_ea16607d7b61445b),
/* harmony export */   szO: () => (/* binding */ __wbg_new_5f486cdf45a04d78),
/* harmony export */   tCB: () => (/* binding */ __wbg_delete_40db93c05c546fb9),
/* harmony export */   tb_: () => (/* binding */ __wbg_then_9e335f6dd892bc11),
/* harmony export */   teL: () => (/* binding */ __wbg_now_c6d7a7d35f74f6f1),
/* harmony export */   tff: () => (/* binding */ __wbg_collectionviewnodeitem_new),
/* harmony export */   tmP: () => (/* binding */ __wbg___wbindgen_is_undefined_52709e72fb9f179c),
/* harmony export */   uND: () => (/* binding */ __wbg_set_body_a3d856b097dfda04),
/* harmony export */   uO9: () => (/* binding */ __wbg___wbindgen_in_41dbb8413020e076),
/* harmony export */   v$b: () => (/* binding */ __wbg_next_e01a967809d1aa68),
/* harmony export */   vWg: () => (/* binding */ __wbg_get_f8121c4a2fc8fb5b),
/* harmony export */   vdI: () => (/* binding */ __wbg_instanceof_Response_9b4d9fd451e051b1),
/* harmony export */   vs4: () => (/* binding */ __wbg_create_e9e35ffcb49d7084),
/* harmony export */   w0Q: () => (/* binding */ __wbg_remove_2a05e82532412f41),
/* harmony export */   w43: () => (/* binding */ __wbg_abort_60dcb252ae0031fc),
/* harmony export */   wb0: () => (/* binding */ __wbg_list_0fdaff8918a551c3),
/* harmony export */   xFt: () => (/* binding */ __wbg_list_e9a4d8a1346dd88b),
/* harmony export */   xGw: () => (/* binding */ __wbg_next_11b99ee6237339e3),
/* harmony export */   xSv: () => (/* binding */ __wbg_list_c37805a6bea723d5),
/* harmony export */   xuz: () => (/* binding */ __wbg___wbindgen_number_get_34bb9d9dcfa21373),
/* harmony export */   y2Z: () => (/* binding */ __wbg_done_08ce71ee07e3bd17),
/* harmony export */   y5K: () => (/* binding */ __wbg_set_method_8c015e8bcafd7be1),
/* harmony export */   y7F: () => (/* binding */ __wbg_clear_1885f7bf35006b0c),
/* harmony export */   yLd: () => (/* binding */ __wbg_objectStore_f314ab152a5c7bd0),
/* harmony export */   yj_: () => (/* binding */ __wbg_new_typed_aaaeaf29cf802876),
/* harmony export */   yjh: () => (/* binding */ __wbg_warn_69424c2d92a2fa73),
/* harmony export */   zA4: () => (/* binding */ __wbg_removeBulk_7898e06fc6e85501),
/* harmony export */   zeM: () => (/* binding */ __wbg_performance_757310249566272b),
/* harmony export */   zgG: () => (/* binding */ __wbg_parse_e9eddd2a82c706eb)
/* harmony export */ });
/* unused harmony exports AttachmentsClient, AuthClient, CardLinkedIdType, CipherAdminClient, CipherRepromptType, CipherRiskClient, CipherType, CiphersClient, CollectionViewNodeItem, CollectionViewTree, CollectionsClient, CommercialPasswordManagerClient, CommercialVaultClient, CryptoClient, ExporterClient, FlightRecorderClient, FoldersClient, GeneratorClient, IdentityLinkedIdType, IncomingMessage, IpcClient, IpcClientSubscription, IpcCommunicationBackend, LoginClient, LoginLinkedIdType, OutgoingMessage, PlatformClient, RegistrationClient, RsaError, SecureNoteType, SendAccessClient, SendClient, ServerCommunicationConfigClient, StateClient, TotpClient, UriMatchType, UserCryptoManagementClient, VaultClient, generate_ssh_key, ipcRegisterDiscoverHandler, ipcRequestDiscover, isAccountCryptographyInitializationError, isAcquireCookieError, isAlreadyRunningError, isCallError, isChannelError, isCipherDeleteAttachmentError, isCipherError, isCipherRiskError, isCollectionDecryptError, isCreateCipherAdminError, isCreateCipherError, isCreateFolderError, isCreateSendError, isCryptoClientError, isDatabaseError, isDecryptError, isDecryptFileError, isDeleteAttachmentAdminError, isDeleteCipherAdminError, isDeleteCipherError, isDeriveKeyConnectorError, isDeserializeError, isEditCipherAdminError, isEditCipherError, isEditFolderError, isEditSendError, isEncryptError, isEncryptFileError, isEncryptionSettingsError, isEnrollAdminPasswordResetError, isExportError, isGetCipherError, isGetFolderError, isGetOrganizationCiphersAdminError, isGetSendError, isKeyGenerationError, isMakeKeysError, isMasterPasswordError, isMigrateToKeyConnectorError, isPasswordError, isPasswordLoginError, isPasswordPreloginError, isReceiveError, isRegistrationError, isRequestError, isRestoreCipherAdminError, isRestoreCipherError, isRotateCryptographyStateError, isRotateUserKeysError, isServerCommunicationConfigRepositoryError, isSshKeyExportError, isSshKeyImportError, isStateRegistryError, isStatefulCryptoError, isSubscribeError, isSyncError, isTestError, isTotpError, isTypedReceiveError, isUsernameError */
class AttachmentsClient {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(AttachmentsClient.prototype);
        obj.__wbg_ptr = ptr;
        AttachmentsClientFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        AttachmentsClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_attachmentsclient_free(ptr, 0);
    }
    /**
     * @param {Cipher} cipher
     * @param {AttachmentView} attachment
     * @param {Uint8Array} encrypted_buffer
     * @returns {Uint8Array}
     */
    decrypt_buffer(cipher, attachment, encrypted_buffer) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passArray8ToWasm0(encrypted_buffer, wasm.__wbindgen_malloc);
            const len0 = WASM_VECTOR_LEN;
            wasm.attachmentsclient_decrypt_buffer(retptr, this.__wbg_ptr, addHeapObject(cipher), addHeapObject(attachment), ptr0, len0);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            if (r3) {
                throw takeObject(r2);
            }
            var v2 = getArrayU8FromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 1, 1);
            return v2;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
}
if (Symbol.dispose) AttachmentsClient.prototype[Symbol.dispose] = AttachmentsClient.prototype.free;

/**
 * Subclient containing auth functionality.
 */
class AuthClient {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(AuthClient.prototype);
        obj.__wbg_ptr = ptr;
        AuthClientFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        AuthClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_authclient_free(ptr, 0);
    }
    /**
     * Client for login functionality
     * @param {ClientSettings} client_settings
     * @returns {LoginClient}
     */
    login(client_settings) {
        const ret = wasm.authclient_login(this.__wbg_ptr, addHeapObject(client_settings));
        return LoginClient.__wrap(ret);
    }
    /**
     * Client for initializing user account cryptography and unlock methods after JIT provisioning
     * @returns {RegistrationClient}
     */
    registration() {
        const ret = wasm.authclient_registration(this.__wbg_ptr);
        return RegistrationClient.__wrap(ret);
    }
    /**
     * Client for send access functionality
     * @returns {SendAccessClient}
     */
    send_access() {
        const ret = wasm.authclient_send_access(this.__wbg_ptr);
        return SendAccessClient.__wrap(ret);
    }
}
if (Symbol.dispose) AuthClient.prototype[Symbol.dispose] = AuthClient.prototype.free;

/**
 * @enum {300 | 301 | 302 | 303 | 304 | 305}
 */
const CardLinkedIdType = Object.freeze({
    CardholderName: 300, "300": "CardholderName",
    ExpMonth: 301, "301": "ExpMonth",
    ExpYear: 302, "302": "ExpYear",
    Code: 303, "303": "Code",
    Brand: 304, "304": "Brand",
    Number: 305, "305": "Number",
});

/**
 * Client for performing admin operations on ciphers. Unlike the regular CiphersClient,
 * this client uses the admin server API endpoints, and does not modify local state.
 */
class CipherAdminClient {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(CipherAdminClient.prototype);
        obj.__wbg_ptr = ptr;
        CipherAdminClientFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        CipherAdminClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_cipheradminclient_free(ptr, 0);
    }
    /**
     * Creates a new [Cipher] for an organization, using the admin server endpoints.
     * Creates the Cipher on the server only, does not store it to local state.
     * @param {CipherCreateRequest} request
     * @returns {Promise<CipherView>}
     */
    create(request) {
        const ret = wasm.cipheradminclient_create(this.__wbg_ptr, addHeapObject(request));
        return takeObject(ret);
    }
    /**
     * Deletes the Cipher with the matching CipherId from the server, using the admin endpoint.
     * Affects server data only, does not modify local state.
     * @param {CipherId} cipher_id
     * @returns {Promise<void>}
     */
    delete(cipher_id) {
        const ret = wasm.cipheradminclient_delete(this.__wbg_ptr, addHeapObject(cipher_id));
        return takeObject(ret);
    }
    /**
     * Deletes an attachment from a cipher using the admin endpoint.
     * Affects server data only, does not modify local state.
     * @param {CipherId} cipher_id
     * @param {string} attachment_id
     * @returns {Promise<void>}
     */
    delete_attachment(cipher_id, attachment_id) {
        const ptr0 = passStringToWasm0(attachment_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.cipheradminclient_delete_attachment(this.__wbg_ptr, addHeapObject(cipher_id), ptr0, len0);
        return takeObject(ret);
    }
    /**
     * Deletes all Cipher objects with a matching CipherId from the server, using the admin
     * endpoint. Affects server data only, does not modify local state.
     * @param {CipherId[]} cipher_ids
     * @param {OrganizationId} organization_id
     * @returns {Promise<void>}
     */
    delete_many(cipher_ids, organization_id) {
        const ptr0 = passArrayJsValueToWasm0(cipher_ids, wasm.__wbindgen_malloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.cipheradminclient_delete_many(this.__wbg_ptr, ptr0, len0, addHeapObject(organization_id));
        return takeObject(ret);
    }
    /**
     * Edit an existing [Cipher] and save it to the server.
     * @param {CipherEditRequest} request
     * @param {CipherView} original_cipher_view
     * @returns {Promise<CipherView>}
     */
    edit(request, original_cipher_view) {
        const ret = wasm.cipheradminclient_edit(this.__wbg_ptr, addHeapObject(request), addHeapObject(original_cipher_view));
        return takeObject(ret);
    }
    /**
     * @param {OrganizationId} org_id
     * @param {boolean} include_member_items
     * @returns {Promise<ListOrganizationCiphersResult>}
     */
    list_org_ciphers(org_id, include_member_items) {
        const ret = wasm.cipheradminclient_list_org_ciphers(this.__wbg_ptr, addHeapObject(org_id), include_member_items);
        return takeObject(ret);
    }
    /**
     * Restores a soft-deleted cipher on the server, using the admin endpoint.
     * @param {CipherId} cipher_id
     * @returns {Promise<CipherView>}
     */
    restore(cipher_id) {
        const ret = wasm.cipheradminclient_restore(this.__wbg_ptr, addHeapObject(cipher_id));
        return takeObject(ret);
    }
    /**
     * Restores multiple soft-deleted ciphers on the server.
     * @param {CipherId[]} cipher_ids
     * @param {OrganizationId} org_id
     * @returns {Promise<DecryptCipherListResult>}
     */
    restore_many(cipher_ids, org_id) {
        const ptr0 = passArrayJsValueToWasm0(cipher_ids, wasm.__wbindgen_malloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.cipheradminclient_restore_many(this.__wbg_ptr, ptr0, len0, addHeapObject(org_id));
        return takeObject(ret);
    }
    /**
     * Soft-deletes the Cipher with the matching CipherId from the server, using the admin
     * endpoint. Affects server data only, does not modify local state.
     * @param {CipherId} cipher_id
     * @returns {Promise<void>}
     */
    soft_delete(cipher_id) {
        const ret = wasm.cipheradminclient_soft_delete(this.__wbg_ptr, addHeapObject(cipher_id));
        return takeObject(ret);
    }
    /**
     * Soft-deletes all Cipher objects for the given CipherIds from the server, using the admin
     * endpoint. Affects server data only, does not modify local state.
     * @param {CipherId[]} cipher_ids
     * @param {OrganizationId} organization_id
     * @returns {Promise<void>}
     */
    soft_delete_many(cipher_ids, organization_id) {
        const ptr0 = passArrayJsValueToWasm0(cipher_ids, wasm.__wbindgen_malloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.cipheradminclient_soft_delete_many(this.__wbg_ptr, ptr0, len0, addHeapObject(organization_id));
        return takeObject(ret);
    }
    /**
     * Adds the cipher matched by [CipherId] to any number of collections on the server.
     * @param {CipherId} cipher_id
     * @param {CollectionId[]} collection_ids
     * @returns {Promise<CipherView>}
     */
    update_collection(cipher_id, collection_ids) {
        const ptr0 = passArrayJsValueToWasm0(collection_ids, wasm.__wbindgen_malloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.cipheradminclient_update_collection(this.__wbg_ptr, addHeapObject(cipher_id), ptr0, len0);
        return takeObject(ret);
    }
}
if (Symbol.dispose) CipherAdminClient.prototype[Symbol.dispose] = CipherAdminClient.prototype.free;

/**
 * @enum {0 | 1}
 */
const CipherRepromptType = Object.freeze({
    None: 0, "0": "None",
    Password: 1, "1": "Password",
});

/**
 * Client for evaluating credential risk for login ciphers.
 */
class CipherRiskClient {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(CipherRiskClient.prototype);
        obj.__wbg_ptr = ptr;
        CipherRiskClientFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        CipherRiskClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_cipherriskclient_free(ptr, 0);
    }
    /**
     * Evaluate security risks for multiple login ciphers concurrently.
     *
     * For each cipher:
     * 1. Calculates password strength (0-4) using zxcvbn with cipher-specific context
     * 2. Optionally checks if the password has been exposed via Have I Been Pwned API
     * 3. Counts how many times the password is reused in the provided `password_map`
     *
     * Returns a vector of `CipherRisk` results, one for each input cipher.
     *
     * ## HIBP Check Results (`exposed_result` field)
     *
     * The `exposed_result` field uses the `ExposedPasswordResult` enum with three possible states:
     * - `NotChecked`: Password exposure check was not performed because:
     *   - `check_exposed` option was `false`, or
     *   - Password was empty
     * - `Found(n)`: Successfully checked via HIBP API, password appears in `n` data breaches
     * - `Error(msg)`: HIBP API request failed with error message `msg`
     *
     * # Errors
     *
     * This method only returns `Err` for internal logic failures. HIBP API errors are
     * captured per-cipher in the `exposed_result` field as `ExposedPasswordResult::Error(msg)`.
     * @param {CipherLoginDetails[]} login_details
     * @param {CipherRiskOptions} options
     * @returns {Promise<CipherRiskResult[]>}
     */
    compute_risk(login_details, options) {
        const ptr0 = passArrayJsValueToWasm0(login_details, wasm.__wbindgen_malloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.cipherriskclient_compute_risk(this.__wbg_ptr, ptr0, len0, addHeapObject(options));
        return takeObject(ret);
    }
    /**
     * Build password reuse map for a list of login ciphers.
     *
     * Returns a map where keys are passwords and values are the number of times
     * each password appears in the provided list. This map can be passed to `compute_risk()`
     * to enable password reuse detection.
     * @param {CipherLoginDetails[]} login_details
     * @returns {PasswordReuseMap}
     */
    password_reuse_map(login_details) {
        const ptr0 = passArrayJsValueToWasm0(login_details, wasm.__wbindgen_malloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.cipherriskclient_password_reuse_map(this.__wbg_ptr, ptr0, len0);
        return takeObject(ret);
    }
}
if (Symbol.dispose) CipherRiskClient.prototype[Symbol.dispose] = CipherRiskClient.prototype.free;

/**
 * @enum {1 | 2 | 3 | 4 | 5}
 */
const CipherType = Object.freeze({
    Login: 1, "1": "Login",
    SecureNote: 2, "2": "SecureNote",
    Card: 3, "3": "Card",
    Identity: 4, "4": "Identity",
    SshKey: 5, "5": "SshKey",
});

class CiphersClient {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(CiphersClient.prototype);
        obj.__wbg_ptr = ptr;
        CiphersClientFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        CiphersClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_ciphersclient_free(ptr, 0);
    }
    /**
     * Returns a new client for performing admin operations.
     * Uses the admin server API endpoints and does not modify local state.
     * @returns {CipherAdminClient}
     */
    admin() {
        const ret = wasm.ciphersclient_admin(this.__wbg_ptr);
        return CipherAdminClient.__wrap(ret);
    }
    /**
     * Creates a new [Cipher] and saves it to the server.
     * @param {CipherCreateRequest} request
     * @returns {Promise<CipherView>}
     */
    create(request) {
        const ret = wasm.ciphersclient_create(this.__wbg_ptr, addHeapObject(request));
        return takeObject(ret);
    }
    /**
     * @param {Cipher} cipher
     * @returns {Promise<CipherView>}
     */
    decrypt(cipher) {
        const ret = wasm.ciphersclient_decrypt(this.__wbg_ptr, addHeapObject(cipher));
        return takeObject(ret);
    }
    /**
     * @param {CipherView} cipher_view
     * @returns {Fido2CredentialView[]}
     */
    decrypt_fido2_credentials(cipher_view) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            wasm.ciphersclient_decrypt_fido2_credentials(retptr, this.__wbg_ptr, addHeapObject(cipher_view));
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            if (r3) {
                throw takeObject(r2);
            }
            var v1 = getArrayJsValueFromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 4, 4);
            return v1;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * @param {CipherView} cipher_view
     * @returns {string}
     */
    decrypt_fido2_private_key(cipher_view) {
        let deferred2_0;
        let deferred2_1;
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            wasm.ciphersclient_decrypt_fido2_private_key(retptr, this.__wbg_ptr, addHeapObject(cipher_view));
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            var ptr1 = r0;
            var len1 = r1;
            if (r3) {
                ptr1 = 0; len1 = 0;
                throw takeObject(r2);
            }
            deferred2_0 = ptr1;
            deferred2_1 = len1;
            return getStringFromWasm0(ptr1, len1);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
            wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
        }
    }
    /**
     * @param {Cipher[]} ciphers
     * @returns {Promise<CipherListView[]>}
     */
    decrypt_list(ciphers) {
        const ptr0 = passArrayJsValueToWasm0(ciphers, wasm.__wbindgen_malloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.ciphersclient_decrypt_list(this.__wbg_ptr, ptr0, len0);
        return takeObject(ret);
    }
    /**
     * Decrypt full cipher list
     * Returns both successfully fully decrypted ciphers and any that failed to decrypt
     * @param {Cipher[]} ciphers
     * @returns {Promise<DecryptCipherResult>}
     */
    decrypt_list_full_with_failures(ciphers) {
        const ptr0 = passArrayJsValueToWasm0(ciphers, wasm.__wbindgen_malloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.ciphersclient_decrypt_list_full_with_failures(this.__wbg_ptr, ptr0, len0);
        return takeObject(ret);
    }
    /**
     * Decrypt cipher list with failures
     * Returns both successfully decrypted ciphers and any that failed to decrypt
     * @param {Cipher[]} ciphers
     * @returns {Promise<DecryptCipherListResult>}
     */
    decrypt_list_with_failures(ciphers) {
        const ptr0 = passArrayJsValueToWasm0(ciphers, wasm.__wbindgen_malloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.ciphersclient_decrypt_list_with_failures(this.__wbg_ptr, ptr0, len0);
        return takeObject(ret);
    }
    /**
     * Deletes the [Cipher] with the matching [CipherId] from the server.
     * @param {CipherId} cipher_id
     * @returns {Promise<void>}
     */
    delete(cipher_id) {
        const ret = wasm.ciphersclient_delete(this.__wbg_ptr, addHeapObject(cipher_id));
        return takeObject(ret);
    }
    /**
     * Deletes an attachment from a cipher, and updates the local repository with the new cipher
     * data returned from the API.
     * @param {CipherId} cipher_id
     * @param {string} attachment_id
     * @returns {Promise<Cipher>}
     */
    delete_attachment(cipher_id, attachment_id) {
        const ptr0 = passStringToWasm0(attachment_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.ciphersclient_delete_attachment(this.__wbg_ptr, addHeapObject(cipher_id), ptr0, len0);
        return takeObject(ret);
    }
    /**
     * Deletes all [Cipher] objects with a matching [CipherId] from the server.
     * @param {CipherId[]} cipher_ids
     * @param {OrganizationId | null} [organization_id]
     * @returns {Promise<void>}
     */
    delete_many(cipher_ids, organization_id) {
        const ptr0 = passArrayJsValueToWasm0(cipher_ids, wasm.__wbindgen_malloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.ciphersclient_delete_many(this.__wbg_ptr, ptr0, len0, isLikeNone(organization_id) ? 0 : addHeapObject(organization_id));
        return takeObject(ret);
    }
    /**
     * Edit an existing [Cipher] and save it to the server.
     * @param {CipherEditRequest} request
     * @returns {Promise<CipherView>}
     */
    edit(request) {
        const ret = wasm.ciphersclient_edit(this.__wbg_ptr, addHeapObject(request));
        return takeObject(ret);
    }
    /**
     * @param {CipherView} cipher_view
     * @returns {Promise<EncryptionContext>}
     */
    encrypt(cipher_view) {
        const ret = wasm.ciphersclient_encrypt(this.__wbg_ptr, addHeapObject(cipher_view));
        return takeObject(ret);
    }
    /**
     * Encrypt a cipher with the provided key. This should only be used when rotating encryption
     * keys in the Web client.
     *
     * Until key rotation is fully implemented in the SDK, this method must be provided the new
     * symmetric key in base64 format. See PM-23084
     *
     * If the cipher has a CipherKey, it will be re-encrypted with the new key.
     * If the cipher does not have a CipherKey and CipherKeyEncryption is enabled, one will be
     * generated using the new key. Otherwise, the cipher's data will be encrypted with the new
     * key directly.
     * @param {CipherView} cipher_view
     * @param {B64} new_key
     * @returns {Promise<EncryptionContext>}
     */
    encrypt_cipher_for_rotation(cipher_view, new_key) {
        const ret = wasm.ciphersclient_encrypt_cipher_for_rotation(this.__wbg_ptr, addHeapObject(cipher_view), addHeapObject(new_key));
        return takeObject(ret);
    }
    /**
     * Encrypt a list of cipher views.
     *
     * This method attempts to encrypt all ciphers in the list. If any cipher
     * fails to encrypt, the entire operation fails and an error is returned.
     * @param {CipherView[]} cipher_views
     * @returns {Promise<EncryptionContext[]>}
     */
    encrypt_list(cipher_views) {
        const ptr0 = passArrayJsValueToWasm0(cipher_views, wasm.__wbindgen_malloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.ciphersclient_encrypt_list(this.__wbg_ptr, ptr0, len0);
        return takeObject(ret);
    }
    /**
     * Get [Cipher] by ID from state and decrypt it to a [CipherView].
     * @param {string} cipher_id
     * @returns {Promise<CipherView>}
     */
    get(cipher_id) {
        const ptr0 = passStringToWasm0(cipher_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.ciphersclient_get(this.__wbg_ptr, ptr0, len0);
        return takeObject(ret);
    }
    /**
     * Get all ciphers from state and decrypt them to full [CipherView], returning both
     * successes and failures. This method will not fail when some ciphers fail to decrypt,
     * allowing for graceful handling of corrupted or problematic cipher data.
     * @returns {Promise<DecryptCipherResult>}
     */
    get_all() {
        const ret = wasm.ciphersclient_get_all(this.__wbg_ptr);
        return takeObject(ret);
    }
    /**
     * Get all ciphers from state and decrypt them to [crate::CipherListView], returning both
     * successes and failures. This method will not fail when some ciphers fail to decrypt,
     * allowing for graceful handling of corrupted or problematic cipher data.
     * @returns {Promise<DecryptCipherListResult>}
     */
    list() {
        const ret = wasm.ciphersclient_list(this.__wbg_ptr);
        return takeObject(ret);
    }
    /**
     * @param {CipherView} cipher_view
     * @param {OrganizationId} organization_id
     * @returns {CipherView}
     */
    move_to_organization(cipher_view, organization_id) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            wasm.ciphersclient_move_to_organization(retptr, this.__wbg_ptr, addHeapObject(cipher_view), addHeapObject(organization_id));
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            if (r2) {
                throw takeObject(r1);
            }
            return takeObject(r0);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Restores a soft-deleted cipher on the server.
     * @param {CipherId} cipher_id
     * @returns {Promise<CipherView>}
     */
    restore(cipher_id) {
        const ret = wasm.ciphersclient_restore(this.__wbg_ptr, addHeapObject(cipher_id));
        return takeObject(ret);
    }
    /**
     * Restores multiple soft-deleted ciphers on the server.
     * @param {CipherId[]} cipher_ids
     * @returns {Promise<DecryptCipherListResult>}
     */
    restore_many(cipher_ids) {
        const ptr0 = passArrayJsValueToWasm0(cipher_ids, wasm.__wbindgen_malloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.ciphersclient_restore_many(this.__wbg_ptr, ptr0, len0);
        return takeObject(ret);
    }
    /**
     * Temporary method used to re-encrypt FIDO2 credentials for a cipher view.
     * Necessary until the TS clients utilize the SDK entirely for FIDO2 credentials management.
     * TS clients create decrypted FIDO2 credentials that need to be encrypted manually when
     * encrypting the rest of the CipherView.
     * TODO: Remove once TS passkey provider implementation uses SDK - PM-8313
     * @param {CipherView} cipher_view
     * @param {Fido2CredentialFullView[]} fido2_credentials
     * @returns {CipherView}
     */
    set_fido2_credentials(cipher_view, fido2_credentials) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passArrayJsValueToWasm0(fido2_credentials, wasm.__wbindgen_malloc);
            const len0 = WASM_VECTOR_LEN;
            wasm.ciphersclient_set_fido2_credentials(retptr, this.__wbg_ptr, addHeapObject(cipher_view), ptr0, len0);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            if (r2) {
                throw takeObject(r1);
            }
            return takeObject(r0);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Moves a cipher into an organization, adds it to collections, and calls the share_cipher API.
     * @param {CipherView} cipher_view
     * @param {OrganizationId} organization_id
     * @param {CollectionId[]} collection_ids
     * @param {CipherView | null} [original_cipher_view]
     * @returns {Promise<CipherView>}
     */
    share_cipher(cipher_view, organization_id, collection_ids, original_cipher_view) {
        const ptr0 = passArrayJsValueToWasm0(collection_ids, wasm.__wbindgen_malloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.ciphersclient_share_cipher(this.__wbg_ptr, addHeapObject(cipher_view), addHeapObject(organization_id), ptr0, len0, isLikeNone(original_cipher_view) ? 0 : addHeapObject(original_cipher_view));
        return takeObject(ret);
    }
    /**
     * Moves a group of ciphers into an organization, adds them to collections, and calls the
     * share_ciphers API.
     * @param {CipherView[]} cipher_views
     * @param {OrganizationId} organization_id
     * @param {CollectionId[]} collection_ids
     * @returns {Promise<CipherView[]>}
     */
    share_ciphers_bulk(cipher_views, organization_id, collection_ids) {
        const ptr0 = passArrayJsValueToWasm0(cipher_views, wasm.__wbindgen_malloc);
        const len0 = WASM_VECTOR_LEN;
        const ptr1 = passArrayJsValueToWasm0(collection_ids, wasm.__wbindgen_malloc);
        const len1 = WASM_VECTOR_LEN;
        const ret = wasm.ciphersclient_share_ciphers_bulk(this.__wbg_ptr, ptr0, len0, addHeapObject(organization_id), ptr1, len1);
        return takeObject(ret);
    }
    /**
     * Soft-deletes the [Cipher] with the matching [CipherId] from the server.
     * @param {CipherId} cipher_id
     * @returns {Promise<void>}
     */
    soft_delete(cipher_id) {
        const ret = wasm.ciphersclient_soft_delete(this.__wbg_ptr, addHeapObject(cipher_id));
        return takeObject(ret);
    }
    /**
     * Soft-deletes all [Cipher] objects for the given [CipherId]s from the server.
     * @param {CipherId[]} cipher_ids
     * @param {OrganizationId | null} [organization_id]
     * @returns {Promise<void>}
     */
    soft_delete_many(cipher_ids, organization_id) {
        const ptr0 = passArrayJsValueToWasm0(cipher_ids, wasm.__wbindgen_malloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.ciphersclient_soft_delete_many(this.__wbg_ptr, ptr0, len0, isLikeNone(organization_id) ? 0 : addHeapObject(organization_id));
        return takeObject(ret);
    }
    /**
     * Adds the cipher matched by [CipherId] to any number of collections on the server.
     * @param {CipherId} cipher_id
     * @param {CollectionId[]} collection_ids
     * @param {boolean} is_admin
     * @returns {Promise<CipherView>}
     */
    update_collection(cipher_id, collection_ids, is_admin) {
        const ptr0 = passArrayJsValueToWasm0(collection_ids, wasm.__wbindgen_malloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.ciphersclient_update_collection(this.__wbg_ptr, addHeapObject(cipher_id), ptr0, len0, is_admin);
        return takeObject(ret);
    }
}
if (Symbol.dispose) CiphersClient.prototype[Symbol.dispose] = CiphersClient.prototype.free;

class CollectionViewNodeItem {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(CollectionViewNodeItem.prototype);
        obj.__wbg_ptr = ptr;
        CollectionViewNodeItemFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        CollectionViewNodeItemFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_collectionviewnodeitem_free(ptr, 0);
    }
    /**
     * @returns {AncestorMap}
     */
    get_ancestors() {
        const ret = wasm.collectionviewnodeitem_get_ancestors(this.__wbg_ptr);
        return takeObject(ret);
    }
    /**
     * @returns {CollectionView[]}
     */
    get_children() {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            wasm.collectionviewnodeitem_get_children(retptr, this.__wbg_ptr);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var v1 = getArrayJsValueFromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 4, 4);
            return v1;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * @returns {CollectionView}
     */
    get_item() {
        const ret = wasm.collectionviewnodeitem_get_item(this.__wbg_ptr);
        return takeObject(ret);
    }
    /**
     * @returns {CollectionView | undefined}
     */
    get_parent() {
        const ret = wasm.collectionviewnodeitem_get_parent(this.__wbg_ptr);
        return takeObject(ret);
    }
}
if (Symbol.dispose) CollectionViewNodeItem.prototype[Symbol.dispose] = CollectionViewNodeItem.prototype.free;

class CollectionViewTree {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(CollectionViewTree.prototype);
        obj.__wbg_ptr = ptr;
        CollectionViewTreeFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        CollectionViewTreeFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_collectionviewtree_free(ptr, 0);
    }
    /**
     * @returns {CollectionViewNodeItem[]}
     */
    get_flat_items() {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            wasm.collectionviewtree_get_flat_items(retptr, this.__wbg_ptr);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var v1 = getArrayJsValueFromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 4, 4);
            return v1;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * @param {CollectionView} collection_view
     * @returns {CollectionViewNodeItem | undefined}
     */
    get_item_for_view(collection_view) {
        const ret = wasm.collectionviewtree_get_item_for_view(this.__wbg_ptr, addHeapObject(collection_view));
        return ret === 0 ? undefined : CollectionViewNodeItem.__wrap(ret);
    }
    /**
     * @returns {CollectionViewNodeItem[]}
     */
    get_root_items() {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            wasm.collectionviewtree_get_root_items(retptr, this.__wbg_ptr);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var v1 = getArrayJsValueFromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 4, 4);
            return v1;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
}
if (Symbol.dispose) CollectionViewTree.prototype[Symbol.dispose] = CollectionViewTree.prototype.free;

class CollectionsClient {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(CollectionsClient.prototype);
        obj.__wbg_ptr = ptr;
        CollectionsClientFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        CollectionsClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_collectionsclient_free(ptr, 0);
    }
    /**
     * @param {Collection} collection
     * @returns {CollectionView}
     */
    decrypt(collection) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            wasm.collectionsclient_decrypt(retptr, this.__wbg_ptr, addHeapObject(collection));
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            if (r2) {
                throw takeObject(r1);
            }
            return takeObject(r0);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * @param {Collection[]} collections
     * @returns {CollectionView[]}
     */
    decrypt_list(collections) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passArrayJsValueToWasm0(collections, wasm.__wbindgen_malloc);
            const len0 = WASM_VECTOR_LEN;
            wasm.collectionsclient_decrypt_list(retptr, this.__wbg_ptr, ptr0, len0);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            if (r3) {
                throw takeObject(r2);
            }
            var v2 = getArrayJsValueFromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 4, 4);
            return v2;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     *
     * Returns the vector of CollectionView objects in a tree structure based on its implemented
     * path().
     * @param {CollectionView[]} collections
     * @returns {CollectionViewTree}
     */
    get_collection_tree(collections) {
        const ptr0 = passArrayJsValueToWasm0(collections, wasm.__wbindgen_malloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.collectionsclient_get_collection_tree(this.__wbg_ptr, ptr0, len0);
        return CollectionViewTree.__wrap(ret);
    }
}
if (Symbol.dispose) CollectionsClient.prototype[Symbol.dispose] = CollectionsClient.prototype.free;

/**
 * Client for bitwarden licensed operations
 */
class CommercialPasswordManagerClient {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(CommercialPasswordManagerClient.prototype);
        obj.__wbg_ptr = ptr;
        CommercialPasswordManagerClientFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        CommercialPasswordManagerClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_commercialpasswordmanagerclient_free(ptr, 0);
    }
    /**
     * Vault item operations
     * @returns {CommercialVaultClient}
     */
    vault() {
        const ret = wasm.commercialpasswordmanagerclient_vault(this.__wbg_ptr);
        return CommercialVaultClient.__wrap(ret);
    }
}
if (Symbol.dispose) CommercialPasswordManagerClient.prototype[Symbol.dispose] = CommercialPasswordManagerClient.prototype.free;

class CommercialVaultClient {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(CommercialVaultClient.prototype);
        obj.__wbg_ptr = ptr;
        CommercialVaultClientFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        CommercialVaultClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_commercialvaultclient_free(ptr, 0);
    }
}
if (Symbol.dispose) CommercialVaultClient.prototype[Symbol.dispose] = CommercialVaultClient.prototype.free;

/**
 * A client for the crypto operations.
 */
class CryptoClient {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(CryptoClient.prototype);
        obj.__wbg_ptr = ptr;
        CryptoClientFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        CryptoClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_cryptoclient_free(ptr, 0);
    }
    /**
     * A stop gap-solution for decrypting with the local user data key, until the WASM client's
     * password generator history encryption and email forwarders encryption is fully migrated to
     * SDK.
     * @param {string} encrypted_plaintext
     * @returns {string}
     */
    decrypt_with_local_user_data_key(encrypted_plaintext) {
        let deferred3_0;
        let deferred3_1;
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passStringToWasm0(encrypted_plaintext, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len0 = WASM_VECTOR_LEN;
            wasm.cryptoclient_decrypt_with_local_user_data_key(retptr, this.__wbg_ptr, ptr0, len0);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            var ptr2 = r0;
            var len2 = r1;
            if (r3) {
                ptr2 = 0; len2 = 0;
                throw takeObject(r2);
            }
            deferred3_0 = ptr2;
            deferred3_1 = len2;
            return getStringFromWasm0(ptr2, len2);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
            wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
        }
    }
    /**
     * A stop gap-solution for encrypting with the local user data key, until the WASM client's
     * password generator history encryption and email forwarders encryption is fully migrated to
     * SDK.
     * @param {string} plaintext
     * @returns {string}
     */
    encrypt_with_local_user_data_key(plaintext) {
        let deferred3_0;
        let deferred3_1;
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passStringToWasm0(plaintext, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len0 = WASM_VECTOR_LEN;
            wasm.cryptoclient_encrypt_with_local_user_data_key(retptr, this.__wbg_ptr, ptr0, len0);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            var ptr2 = r0;
            var len2 = r1;
            if (r3) {
                ptr2 = 0; len2 = 0;
                throw takeObject(r2);
            }
            deferred3_0 = ptr2;
            deferred3_1 = len2;
            return getStringFromWasm0(ptr2, len2);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
            wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
        }
    }
    /**
     * Protects the current user key with the provided PIN. The result can be stored and later
     * used to initialize another client instance by using the PIN and the PIN key with
     * `initialize_user_crypto`.
     * @param {string} pin
     * @returns {EnrollPinResponse}
     */
    enroll_pin(pin) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passStringToWasm0(pin, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len0 = WASM_VECTOR_LEN;
            wasm.cryptoclient_enroll_pin(retptr, this.__wbg_ptr, ptr0, len0);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            if (r2) {
                throw takeObject(r1);
            }
            return takeObject(r0);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Protects the current user key with the provided PIN. The result can be stored and later
     * used to initialize another client instance by using the PIN and the PIN key with
     * `initialize_user_crypto`. The provided pin is encrypted with the user key.
     * @param {string} encrypted_pin
     * @returns {EnrollPinResponse}
     */
    enroll_pin_with_encrypted_pin(encrypted_pin) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passStringToWasm0(encrypted_pin, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len0 = WASM_VECTOR_LEN;
            wasm.cryptoclient_enroll_pin_with_encrypted_pin(retptr, this.__wbg_ptr, ptr0, len0);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            if (r2) {
                throw takeObject(r1);
            }
            return takeObject(r0);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Takes a raw key and returns the corresponding key id. This is used for the biometrics
     * subsystem and should be removed after moving over biometric management to the SDK.
     * @param {Uint8Array} key
     * @returns {Uint8Array | undefined}
     */
    static get_key_id_for_symmetric_key(key) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passArray8ToWasm0(key, wasm.__wbindgen_malloc);
            const len0 = WASM_VECTOR_LEN;
            wasm.cryptoclient_get_key_id_for_symmetric_key(retptr, ptr0, len0);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            if (r3) {
                throw takeObject(r2);
            }
            let v2;
            if (r0 !== 0) {
                v2 = getArrayU8FromWasm0(r0, r1).slice();
                wasm.__wbindgen_free(r0, r1 * 1, 1);
            }
            return v2;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * ⚠️⚠️⚠️ HAZMAT WARNING: DO NOT USE THIS ⚠️⚠️⚠️
     *
     * Get the uses's decrypted encryption key. Note: It's very important
     * to keep this key safe, as it can be used to decrypt all of the user's data. It is
     * only permitted to use for a transition period where side effects such as biometrics
     * and never-lock are set from within the client code.
     * @returns {Promise<B64>}
     */
    get_user_encryption_key() {
        const ret = wasm.cryptoclient_get_user_encryption_key(this.__wbg_ptr);
        return takeObject(ret);
    }
    /**
     * Creates a rotated set of account keys for the current state
     * @returns {UserCryptoV2KeysResponse}
     */
    get_v2_rotated_account_keys() {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            wasm.cryptoclient_get_v2_rotated_account_keys(retptr, this.__wbg_ptr);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            if (r2) {
                throw takeObject(r1);
            }
            return takeObject(r0);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Initialization method for the organization crypto. Needs to be called after
     * `initialize_user_crypto` but before any other crypto operations.
     * @param {InitOrgCryptoRequest} req
     * @returns {Promise<void>}
     */
    initialize_org_crypto(req) {
        const ret = wasm.cryptoclient_initialize_org_crypto(this.__wbg_ptr, addHeapObject(req));
        return takeObject(ret);
    }
    /**
     * Initialization method for the user crypto. Needs to be called before any other crypto
     * operations.
     * @param {InitUserCryptoRequest} req
     * @returns {Promise<void>}
     */
    initialize_user_crypto(req) {
        const ret = wasm.cryptoclient_initialize_user_crypto(this.__wbg_ptr, addHeapObject(req));
        return takeObject(ret);
    }
    /**
     * Generates a new key pair and encrypts the private key with the provided user key.
     * Crypto initialization not required.
     * @param {B64} user_key
     * @returns {MakeKeyPairResponse}
     */
    make_key_pair(user_key) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            wasm.cryptoclient_make_key_pair(retptr, this.__wbg_ptr, addHeapObject(user_key));
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            if (r2) {
                throw takeObject(r1);
            }
            return takeObject(r0);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Makes a new signing key pair and signs the public key for the user
     * @returns {UserCryptoV2KeysResponse}
     */
    make_keys_for_user_crypto_v2() {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            wasm.cryptoclient_make_keys_for_user_crypto_v2(retptr, this.__wbg_ptr);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            if (r2) {
                throw takeObject(r1);
            }
            return takeObject(r0);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Create the data necessary to update the user's kdf settings. The user's encryption key is
     * re-encrypted for the password under the new kdf settings. This returns the re-encrypted
     * user key and the new password hash but does not update sdk state.
     * @param {string} password
     * @param {Kdf} kdf
     * @returns {Promise<UpdateKdfResponse>}
     */
    make_update_kdf(password, kdf) {
        const ptr0 = passStringToWasm0(password, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.cryptoclient_make_update_kdf(this.__wbg_ptr, ptr0, len0, addHeapObject(kdf));
        return takeObject(ret);
    }
    /**
     * Decrypts a `PasswordProtectedKeyEnvelope`, returning the user key, if successful.
     * This is a stop-gap solution, until initialization of the SDK is used.
     * @param {string} pin
     * @param {string} envelope
     * @returns {Uint8Array}
     */
    unseal_password_protected_key_envelope(pin, envelope) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passStringToWasm0(pin, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passStringToWasm0(envelope, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len1 = WASM_VECTOR_LEN;
            wasm.cryptoclient_unseal_password_protected_key_envelope(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            if (r3) {
                throw takeObject(r2);
            }
            var v3 = getArrayU8FromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 1, 1);
            return v3;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Verifies a user's asymmetric keys by decrypting the private key with the provided user
     * key. Returns if the private key is decryptable and if it is a valid matching key.
     * Crypto initialization not required.
     * @param {VerifyAsymmetricKeysRequest} request
     * @returns {VerifyAsymmetricKeysResponse}
     */
    verify_asymmetric_keys(request) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            wasm.cryptoclient_verify_asymmetric_keys(retptr, this.__wbg_ptr, addHeapObject(request));
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            if (r2) {
                throw takeObject(r1);
            }
            return takeObject(r0);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
}
if (Symbol.dispose) CryptoClient.prototype[Symbol.dispose] = CryptoClient.prototype.free;

class ExporterClient {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(ExporterClient.prototype);
        obj.__wbg_ptr = ptr;
        ExporterClientFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        ExporterClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_exporterclient_free(ptr, 0);
    }
    /**
     * Credential Exchange Format (CXF)
     *
     * *Warning:* Expect this API to be unstable, and it will change in the future.
     *
     * For use with Apple using [ASCredentialExportManager](https://developer.apple.com/documentation/authenticationservices/ascredentialexportmanager).
     * Ideally, the input should be immediately serialized from [ASImportableAccount](https://developer.apple.com/documentation/authenticationservices/asimportableaccount).
     * @param {Account} account
     * @param {Cipher[]} ciphers
     * @returns {string}
     */
    export_cxf(account, ciphers) {
        let deferred3_0;
        let deferred3_1;
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passArrayJsValueToWasm0(ciphers, wasm.__wbindgen_malloc);
            const len0 = WASM_VECTOR_LEN;
            wasm.exporterclient_export_cxf(retptr, this.__wbg_ptr, addHeapObject(account), ptr0, len0);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            var ptr2 = r0;
            var len2 = r1;
            if (r3) {
                ptr2 = 0; len2 = 0;
                throw takeObject(r2);
            }
            deferred3_0 = ptr2;
            deferred3_1 = len2;
            return getStringFromWasm0(ptr2, len2);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
            wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
        }
    }
    /**
     * @param {Collection[]} collections
     * @param {Cipher[]} ciphers
     * @param {ExportFormat} format
     * @returns {string}
     */
    export_organization_vault(collections, ciphers, format) {
        let deferred4_0;
        let deferred4_1;
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passArrayJsValueToWasm0(collections, wasm.__wbindgen_malloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passArrayJsValueToWasm0(ciphers, wasm.__wbindgen_malloc);
            const len1 = WASM_VECTOR_LEN;
            wasm.exporterclient_export_organization_vault(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1, addHeapObject(format));
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            var ptr3 = r0;
            var len3 = r1;
            if (r3) {
                ptr3 = 0; len3 = 0;
                throw takeObject(r2);
            }
            deferred4_0 = ptr3;
            deferred4_1 = len3;
            return getStringFromWasm0(ptr3, len3);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
            wasm.__wbindgen_free(deferred4_0, deferred4_1, 1);
        }
    }
    /**
     * @param {Folder[]} folders
     * @param {Cipher[]} ciphers
     * @param {ExportFormat} format
     * @returns {Promise<string>}
     */
    export_vault(folders, ciphers, format) {
        const ptr0 = passArrayJsValueToWasm0(folders, wasm.__wbindgen_malloc);
        const len0 = WASM_VECTOR_LEN;
        const ptr1 = passArrayJsValueToWasm0(ciphers, wasm.__wbindgen_malloc);
        const len1 = WASM_VECTOR_LEN;
        const ret = wasm.exporterclient_export_vault(this.__wbg_ptr, ptr0, len0, ptr1, len1, addHeapObject(format));
        return takeObject(ret);
    }
    /**
     * Credential Exchange Format (CXF)
     *
     * *Warning:* Expect this API to be unstable, and it will change in the future.
     *
     * For use with Apple using [ASCredentialExportManager](https://developer.apple.com/documentation/authenticationservices/ascredentialexportmanager).
     * Ideally, the input should be immediately serialized from [ASImportableAccount](https://developer.apple.com/documentation/authenticationservices/asimportableaccount).
     * @param {string} payload
     * @returns {Cipher[]}
     */
    import_cxf(payload) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passStringToWasm0(payload, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len0 = WASM_VECTOR_LEN;
            wasm.exporterclient_import_cxf(retptr, this.__wbg_ptr, ptr0, len0);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            if (r3) {
                throw takeObject(r2);
            }
            var v2 = getArrayJsValueFromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 4, 4);
            return v2;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
}
if (Symbol.dispose) ExporterClient.prototype[Symbol.dispose] = ExporterClient.prototype.free;

/**
 * Represents the type of a [FieldView].
 * @enum {0 | 1 | 2 | 3}
 */
const FieldType = Object.freeze({
    /**
     * Text field
     */
    Text: 0, "0": "Text",
    /**
     * Hidden text field
     */
    Hidden: 1, "1": "Hidden",
    /**
     * Boolean field
     */
    Boolean: 2, "2": "Boolean",
    /**
     * Linked field
     */
    Linked: 3, "3": "Linked",
});

/**
 * WASM client for reading Flight Recorder logs.
 *
 * The underlying buffer is global (initialized in [`init_sdk`](crate::init_sdk)),
 * so this client is a stateless handle for WASM access.
 */
class FlightRecorderClient {
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        FlightRecorderClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_flightrecorderclient_free(ptr, 0);
    }
    /**
     * Get the current event count without reading event contents.
     * @returns {number}
     */
    count() {
        const ret = wasm.flightrecorderclient_count(this.__wbg_ptr);
        return ret >>> 0;
    }
    /**
     * Create a new `FlightRecorderClient`.
     */
    constructor() {
        const ret = wasm.flightrecorderclient_new();
        this.__wbg_ptr = ret >>> 0;
        FlightRecorderClientFinalization.register(this, this.__wbg_ptr, this);
        return this;
    }
    /**
     * Read all events currently in the Flight Recorder buffer.
     * @returns {FlightRecorderEvent[]}
     */
    read() {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            wasm.flightrecorderclient_read(retptr, this.__wbg_ptr);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var v1 = getArrayJsValueFromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 4, 4);
            return v1;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
}
if (Symbol.dispose) FlightRecorderClient.prototype[Symbol.dispose] = FlightRecorderClient.prototype.free;

/**
 * Wrapper for folder specific functionality.
 */
class FoldersClient {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(FoldersClient.prototype);
        obj.__wbg_ptr = ptr;
        FoldersClientFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        FoldersClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_foldersclient_free(ptr, 0);
    }
    /**
     * Create a new [Folder] and save it to the server.
     * @param {FolderAddEditRequest} request
     * @returns {Promise<FolderView>}
     */
    create(request) {
        const ret = wasm.foldersclient_create(this.__wbg_ptr, addHeapObject(request));
        return takeObject(ret);
    }
    /**
     * Encrypt a [Folder] to [FolderView].
     * @param {Folder} folder
     * @returns {FolderView}
     */
    decrypt(folder) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            wasm.foldersclient_decrypt(retptr, this.__wbg_ptr, addHeapObject(folder));
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            if (r2) {
                throw takeObject(r1);
            }
            return takeObject(r0);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Decrypt a list of [Folder]s to a list of [FolderView]s.
     * @param {Folder[]} folders
     * @returns {FolderView[]}
     */
    decrypt_list(folders) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passArrayJsValueToWasm0(folders, wasm.__wbindgen_malloc);
            const len0 = WASM_VECTOR_LEN;
            wasm.foldersclient_decrypt_list(retptr, this.__wbg_ptr, ptr0, len0);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            if (r3) {
                throw takeObject(r2);
            }
            var v2 = getArrayJsValueFromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 4, 4);
            return v2;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Edit the [Folder] and save it to the server.
     * @param {FolderId} folder_id
     * @param {FolderAddEditRequest} request
     * @returns {Promise<FolderView>}
     */
    edit(folder_id, request) {
        const ret = wasm.foldersclient_edit(this.__wbg_ptr, addHeapObject(folder_id), addHeapObject(request));
        return takeObject(ret);
    }
    /**
     * Encrypt a [FolderView] to a [Folder].
     * @param {FolderView} folder_view
     * @returns {Folder}
     */
    encrypt(folder_view) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            wasm.foldersclient_encrypt(retptr, this.__wbg_ptr, addHeapObject(folder_view));
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            if (r2) {
                throw takeObject(r1);
            }
            return takeObject(r0);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Get a specific [Folder] by its ID from state and decrypt it to a [FolderView].
     * @param {FolderId} folder_id
     * @returns {Promise<FolderView>}
     */
    get(folder_id) {
        const ret = wasm.foldersclient_get(this.__wbg_ptr, addHeapObject(folder_id));
        return takeObject(ret);
    }
    /**
     * Get all folders from state and decrypt them to a list of [FolderView].
     * @returns {Promise<FolderView[]>}
     */
    list() {
        const ret = wasm.foldersclient_list(this.__wbg_ptr);
        return takeObject(ret);
    }
}
if (Symbol.dispose) FoldersClient.prototype[Symbol.dispose] = FoldersClient.prototype.free;

class GeneratorClient {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(GeneratorClient.prototype);
        obj.__wbg_ptr = ptr;
        GeneratorClientFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        GeneratorClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_generatorclient_free(ptr, 0);
    }
    /**
     * Generates a random passphrase.
     * A passphrase is a combination of random words separated by a character.
     * An example of passphrase is `correct horse battery staple`.
     *
     * The number of words and their case, the word separator, and the inclusion of
     * a number in the passphrase can be customized using the `input` parameter.
     *
     * # Examples
     *
     * ```
     * use bitwarden_core::Client;
     * use bitwarden_generators::{GeneratorClientsExt, PassphraseError, PassphraseGeneratorRequest};
     *
     * async fn test() -> Result<(), PassphraseError> {
     *     let input = PassphraseGeneratorRequest {
     *         num_words: 4,
     *         ..Default::default()
     *     };
     *     let passphrase = Client::new(None).generator().passphrase(input).unwrap();
     *     println!("{}", passphrase);
     *     Ok(())
     * }
     * ```
     * @param {PassphraseGeneratorRequest} input
     * @returns {string}
     */
    passphrase(input) {
        let deferred2_0;
        let deferred2_1;
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            wasm.generatorclient_passphrase(retptr, this.__wbg_ptr, addHeapObject(input));
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            var ptr1 = r0;
            var len1 = r1;
            if (r3) {
                ptr1 = 0; len1 = 0;
                throw takeObject(r2);
            }
            deferred2_0 = ptr1;
            deferred2_1 = len1;
            return getStringFromWasm0(ptr1, len1);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
            wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
        }
    }
    /**
     * Generates a random password.
     *
     * The character sets and password length can be customized using the `input` parameter.
     *
     * # Examples
     *
     * ```
     * use bitwarden_core::Client;
     * use bitwarden_generators::{GeneratorClientsExt, PassphraseError, PasswordGeneratorRequest};
     *
     * async fn test() -> Result<(), PassphraseError> {
     *     let input = PasswordGeneratorRequest {
     *         lowercase: true,
     *         uppercase: true,
     *         numbers: true,
     *         length: 20,
     *         ..Default::default()
     *     };
     *     let password = Client::new(None).generator().password(input).unwrap();
     *     println!("{}", password);
     *     Ok(())
     * }
     * ```
     * @param {PasswordGeneratorRequest} input
     * @returns {string}
     */
    password(input) {
        let deferred2_0;
        let deferred2_1;
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            wasm.generatorclient_password(retptr, this.__wbg_ptr, addHeapObject(input));
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            var ptr1 = r0;
            var len1 = r1;
            if (r3) {
                ptr1 = 0; len1 = 0;
                throw takeObject(r2);
            }
            deferred2_0 = ptr1;
            deferred2_1 = len1;
            return getStringFromWasm0(ptr1, len1);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
            wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
        }
    }
}
if (Symbol.dispose) GeneratorClient.prototype[Symbol.dispose] = GeneratorClient.prototype.free;

/**
 * @enum {400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418}
 */
const IdentityLinkedIdType = Object.freeze({
    Title: 400, "400": "Title",
    MiddleName: 401, "401": "MiddleName",
    Address1: 402, "402": "Address1",
    Address2: 403, "403": "Address2",
    Address3: 404, "404": "Address3",
    City: 405, "405": "City",
    State: 406, "406": "State",
    PostalCode: 407, "407": "PostalCode",
    Country: 408, "408": "Country",
    Company: 409, "409": "Company",
    Email: 410, "410": "Email",
    Phone: 411, "411": "Phone",
    Ssn: 412, "412": "Ssn",
    Username: 413, "413": "Username",
    PassportNumber: 414, "414": "PassportNumber",
    LicenseNumber: 415, "415": "LicenseNumber",
    FirstName: 416, "416": "FirstName",
    LastName: 417, "417": "LastName",
    FullName: 418, "418": "FullName",
});

/**
 * An untyped IPC message received from another endpoint.
 */
class IncomingMessage {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(IncomingMessage.prototype);
        obj.__wbg_ptr = ptr;
        IncomingMessageFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        IncomingMessageFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_incomingmessage_free(ptr, 0);
    }
    /**
     * Destination endpoint that received this message.
     * @returns {Endpoint}
     */
    get destination() {
        const ret = wasm.__wbg_get_incomingmessage_destination(this.__wbg_ptr);
        return takeObject(ret);
    }
    /**
     * Serialized payload bytes.
     * @returns {Uint8Array}
     */
    get payload() {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            wasm.__wbg_get_incomingmessage_payload(retptr, this.__wbg_ptr);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var v1 = getArrayU8FromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 1, 1);
            return v1;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Source that sent this message, with per-variant metadata.
     * @returns {Source}
     */
    get source() {
        const ret = wasm.__wbg_get_incomingmessage_source(this.__wbg_ptr);
        return takeObject(ret);
    }
    /**
     * Optional topic used for routing/dispatch.
     * @returns {string | undefined}
     */
    get topic() {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            wasm.__wbg_get_incomingmessage_topic(retptr, this.__wbg_ptr);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            let v1;
            if (r0 !== 0) {
                v1 = getStringFromWasm0(r0, r1).slice();
                wasm.__wbindgen_free(r0, r1 * 1, 1);
            }
            return v1;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Create an incoming IPC message from raw payload bytes.
     * @param {Uint8Array} payload
     * @param {Endpoint} destination
     * @param {Source} source
     * @param {string | null} [topic]
     */
    constructor(payload, destination, source, topic) {
        const ptr0 = passArray8ToWasm0(payload, wasm.__wbindgen_malloc);
        const len0 = WASM_VECTOR_LEN;
        var ptr1 = isLikeNone(topic) ? 0 : passStringToWasm0(topic, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
        var len1 = WASM_VECTOR_LEN;
        const ret = wasm.incomingmessage_new(ptr0, len0, addHeapObject(destination), addHeapObject(source), ptr1, len1);
        this.__wbg_ptr = ret >>> 0;
        IncomingMessageFinalization.register(this, this.__wbg_ptr, this);
        return this;
    }
    /**
     * Try to parse the payload as JSON.
     * @returns {any} The parsed JSON value, or undefined if the payload is not valid JSON.
     */
    parse_payload_as_json() {
        const ret = wasm.incomingmessage_parse_payload_as_json(this.__wbg_ptr);
        return takeObject(ret);
    }
    /**
     * Destination endpoint that received this message.
     * @param {Endpoint} arg0
     */
    set destination(arg0) {
        wasm.__wbg_set_incomingmessage_destination(this.__wbg_ptr, addHeapObject(arg0));
    }
    /**
     * Serialized payload bytes.
     * @param {Uint8Array} arg0
     */
    set payload(arg0) {
        const ptr0 = passArray8ToWasm0(arg0, wasm.__wbindgen_malloc);
        const len0 = WASM_VECTOR_LEN;
        wasm.__wbg_set_incomingmessage_payload(this.__wbg_ptr, ptr0, len0);
    }
    /**
     * Source that sent this message, with per-variant metadata.
     * @param {Source} arg0
     */
    set source(arg0) {
        wasm.__wbg_set_incomingmessage_source(this.__wbg_ptr, addHeapObject(arg0));
    }
    /**
     * Optional topic used for routing/dispatch.
     * @param {string | null} [arg0]
     */
    set topic(arg0) {
        var ptr0 = isLikeNone(arg0) ? 0 : passStringToWasm0(arg0, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
        var len0 = WASM_VECTOR_LEN;
        wasm.__wbg_set_incomingmessage_topic(this.__wbg_ptr, ptr0, len0);
    }
}
if (Symbol.dispose) IncomingMessage.prototype[Symbol.dispose] = IncomingMessage.prototype.free;

/**
 * JavaScript wrapper around the IPC client. For more information, see the
 * [`IpcClient`] trait documentation.
 */
class IpcClient {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(IpcClient.prototype);
        obj.__wbg_ptr = ptr;
        IpcClientFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        IpcClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_ipcclient_free(ptr, 0);
    }
    /**
     * @returns {boolean}
     */
    isRunning() {
        const ret = wasm.ipcclient_isRunning(this.__wbg_ptr);
        return ret !== 0;
    }
    /**
     * Create a new `IpcClient` instance with a client-managed session repository for saving
     * sessions using State Provider.
     * @param {IpcCommunicationBackend} communication_provider
     * @param {IpcSessionRepository} session_repository
     * @returns {IpcClient}
     */
    static newWithClientManagedSessions(communication_provider, session_repository) {
        _assertClass(communication_provider, IpcCommunicationBackend);
        const ret = wasm.ipcclient_newWithClientManagedSessions(communication_provider.__wbg_ptr, addHeapObject(session_repository));
        return IpcClient.__wrap(ret);
    }
    /**
     * Create a new `IpcClient` instance with an in-memory session repository for saving
     * sessions within the SDK.
     * @param {IpcCommunicationBackend} communication_provider
     * @returns {IpcClient}
     */
    static newWithSdkInMemorySessions(communication_provider) {
        _assertClass(communication_provider, IpcCommunicationBackend);
        const ret = wasm.ipcclient_newWithSdkInMemorySessions(communication_provider.__wbg_ptr);
        return IpcClient.__wrap(ret);
    }
    /**
     * @param {OutgoingMessage} message
     * @returns {Promise<void>}
     */
    send(message) {
        _assertClass(message, OutgoingMessage);
        var ptr0 = message.__destroy_into_raw();
        const ret = wasm.ipcclient_send(this.__wbg_ptr, ptr0);
        return takeObject(ret);
    }
    /**
     * @param {AbortSignal | null} [abort_signal]
     * @returns {Promise<void>}
     */
    start(abort_signal) {
        const ret = wasm.ipcclient_start(this.__wbg_ptr, isLikeNone(abort_signal) ? 0 : addHeapObject(abort_signal));
        return takeObject(ret);
    }
    /**
     * @returns {Promise<IpcClientSubscription>}
     */
    subscribe() {
        const ret = wasm.ipcclient_subscribe(this.__wbg_ptr);
        return takeObject(ret);
    }
}
if (Symbol.dispose) IpcClient.prototype[Symbol.dispose] = IpcClient.prototype.free;

/**
 * JavaScript wrapper around the IPC client subscription. For more information, see the
 * [IpcClientSubscription](crate::IpcClientSubscription) documentation.
 */
class IpcClientSubscription {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(IpcClientSubscription.prototype);
        obj.__wbg_ptr = ptr;
        IpcClientSubscriptionFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        IpcClientSubscriptionFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_ipcclientsubscription_free(ptr, 0);
    }
    /**
     * @param {AbortSignal | null} [abort_signal]
     * @returns {Promise<IncomingMessage>}
     */
    receive(abort_signal) {
        const ret = wasm.ipcclientsubscription_receive(this.__wbg_ptr, isLikeNone(abort_signal) ? 0 : addHeapObject(abort_signal));
        return takeObject(ret);
    }
}
if (Symbol.dispose) IpcClientSubscription.prototype[Symbol.dispose] = IpcClientSubscription.prototype.free;

/**
 * JavaScript implementation of the `CommunicationBackend` trait for IPC communication.
 */
class IpcCommunicationBackend {
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        IpcCommunicationBackendFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_ipccommunicationbackend_free(ptr, 0);
    }
    /**
     * Creates a new instance of the JavaScript communication backend.
     * @param {IpcCommunicationBackendSender} sender
     */
    constructor(sender) {
        const ret = wasm.ipccommunicationbackend_new(addHeapObject(sender));
        this.__wbg_ptr = ret >>> 0;
        IpcCommunicationBackendFinalization.register(this, this.__wbg_ptr, this);
        return this;
    }
    /**
     * Used by JavaScript to provide an incoming message to the IPC framework.
     * @param {IncomingMessage} message
     */
    receive(message) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            _assertClass(message, IncomingMessage);
            var ptr0 = message.__destroy_into_raw();
            wasm.ipccommunicationbackend_receive(retptr, this.__wbg_ptr, ptr0);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            if (r1) {
                throw takeObject(r0);
            }
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
}
if (Symbol.dispose) IpcCommunicationBackend.prototype[Symbol.dispose] = IpcCommunicationBackend.prototype.free;

/**
 * @enum {0 | 1 | 2 | 3 | 4}
 */
const LogLevel = Object.freeze({
    Trace: 0, "0": "Trace",
    Debug: 1, "1": "Debug",
    Info: 2, "2": "Info",
    Warn: 3, "3": "Warn",
    Error: 4, "4": "Error",
});

/**
 * Client for authenticating Bitwarden users.
 *
 * Handles unauthenticated operations to obtain access tokens from the Identity API.
 * After successful authentication, use the returned tokens to create an authenticated core client.
 *
 * # Lifecycle
 *
 * 1. Create `LoginClient` via `AuthClient`
 * 2. Call login method
 * 3. Use returned tokens with authenticated core client
 *
 * # Password Login Example
 *
 * ```rust,no_run
 * # use bitwarden_auth::{AuthClient, login::login_via_password::PasswordLoginRequest};
 * # use bitwarden_auth::login::models::{LoginRequest, LoginDeviceRequest, LoginResponse};
 * # use bitwarden_core::{Client, ClientSettings, DeviceType};
 * # async fn example(email: String, password: String) -> Result<(), Box<dyn std::error::Error>> {
 * // Create auth client
 * let client = Client::new(None);
 * let auth_client = AuthClient::new(client);
 *
 * // Configure client settings and create login client
 * let settings = ClientSettings {
 *     identity_url: "https://identity.bitwarden.com".to_string(),
 *     api_url: "https://api.bitwarden.com".to_string(),
 *     user_agent: "MyApp/1.0".to_string(),
 *     device_type: DeviceType::SDK,
 *     device_identifier: None,
 *     bitwarden_client_version: None,
 *     bitwarden_package_type: None,
 * };
 * let login_client = auth_client.login(settings);
 *
 * // Get user's KDF config
 * let prelogin = login_client.get_password_prelogin(email.clone()).await?;
 *
 * // Login with credentials
 * let response = login_client.login_via_password(PasswordLoginRequest {
 *     login_request: LoginRequest {
 *         client_id: "connector".to_string(),
 *         device: LoginDeviceRequest {
 *             device_type: DeviceType::SDK,
 *             device_identifier: "device-id".to_string(),
 *             device_name: "My Device".to_string(),
 *             device_push_token: None,
 *         },
 *     },
 *     email,
 *     password,
 *     prelogin_response: prelogin,
 * }).await?;
 *
 * // Use tokens from response for authenticated requests
 * match response {
 *     LoginResponse::Authenticated(success) => {
 *         let access_token = success.access_token;
 *         // Use access_token for authenticated requests
 *     }
 * }
 * # Ok(())
 * # }
 * ```
 */
class LoginClient {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(LoginClient.prototype);
        obj.__wbg_ptr = ptr;
        LoginClientFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        LoginClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_loginclient_free(ptr, 0);
    }
    /**
     * Retrieves the data required before authenticating with a password.
     * This includes the user's KDF configuration needed to properly derive the master key.
     * @param {string} email
     * @returns {Promise<PasswordPreloginResponse>}
     */
    get_password_prelogin(email) {
        const ptr0 = passStringToWasm0(email, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.loginclient_get_password_prelogin(this.__wbg_ptr, ptr0, len0);
        return takeObject(ret);
    }
    /**
     * Authenticates a user via email and master password.
     *
     * Derives the master password hash using KDF settings from prelogin, then sends
     * the authentication request to obtain access tokens and vault keys.
     * @param {PasswordLoginRequest} request
     * @returns {Promise<LoginResponse>}
     */
    login_via_password(request) {
        const ret = wasm.loginclient_login_via_password(this.__wbg_ptr, addHeapObject(request));
        return takeObject(ret);
    }
}
if (Symbol.dispose) LoginClient.prototype[Symbol.dispose] = LoginClient.prototype.free;

/**
 * @enum {100 | 101}
 */
const LoginLinkedIdType = Object.freeze({
    Username: 100, "100": "Username",
    Password: 101, "101": "Password",
});

/**
 * An untyped IPC message to be sent to another endpoint.
 */
class OutgoingMessage {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(OutgoingMessage.prototype);
        obj.__wbg_ptr = ptr;
        OutgoingMessageFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        OutgoingMessageFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_outgoingmessage_free(ptr, 0);
    }
    /**
     * Destination endpoint for this message.
     * @returns {Endpoint}
     */
    get destination() {
        const ret = wasm.__wbg_get_outgoingmessage_destination(this.__wbg_ptr);
        return takeObject(ret);
    }
    /**
     * Serialized payload bytes.
     * @returns {Uint8Array}
     */
    get payload() {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            wasm.__wbg_get_outgoingmessage_payload(retptr, this.__wbg_ptr);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var v1 = getArrayU8FromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 1, 1);
            return v1;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Optional topic used for routing/dispatch.
     * @returns {string | undefined}
     */
    get topic() {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            wasm.__wbg_get_outgoingmessage_topic(retptr, this.__wbg_ptr);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            let v1;
            if (r0 !== 0) {
                v1 = getStringFromWasm0(r0, r1).slice();
                wasm.__wbindgen_free(r0, r1 * 1, 1);
            }
            return v1;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Create an outgoing IPC message from raw payload bytes.
     * @param {Uint8Array} payload
     * @param {Endpoint} destination
     * @param {string | null} [topic]
     */
    constructor(payload, destination, topic) {
        const ptr0 = passArray8ToWasm0(payload, wasm.__wbindgen_malloc);
        const len0 = WASM_VECTOR_LEN;
        var ptr1 = isLikeNone(topic) ? 0 : passStringToWasm0(topic, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
        var len1 = WASM_VECTOR_LEN;
        const ret = wasm.outgoingmessage_new(ptr0, len0, addHeapObject(destination), ptr1, len1);
        this.__wbg_ptr = ret >>> 0;
        OutgoingMessageFinalization.register(this, this.__wbg_ptr, this);
        return this;
    }
    /**
     * Create a new message and encode the payload as JSON.
     * @param {any} payload
     * @param {Endpoint} destination
     * @param {string | null} [topic]
     * @returns {OutgoingMessage}
     */
    static new_json_payload(payload, destination, topic) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            var ptr0 = isLikeNone(topic) ? 0 : passStringToWasm0(topic, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            var len0 = WASM_VECTOR_LEN;
            wasm.outgoingmessage_new_json_payload(retptr, addHeapObject(payload), addHeapObject(destination), ptr0, len0);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            if (r2) {
                throw takeObject(r1);
            }
            return OutgoingMessage.__wrap(r0);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Destination endpoint for this message.
     * @param {Endpoint} arg0
     */
    set destination(arg0) {
        wasm.__wbg_set_outgoingmessage_destination(this.__wbg_ptr, addHeapObject(arg0));
    }
    /**
     * Serialized payload bytes.
     * @param {Uint8Array} arg0
     */
    set payload(arg0) {
        const ptr0 = passArray8ToWasm0(arg0, wasm.__wbindgen_malloc);
        const len0 = WASM_VECTOR_LEN;
        wasm.__wbg_set_outgoingmessage_payload(this.__wbg_ptr, ptr0, len0);
    }
    /**
     * Optional topic used for routing/dispatch.
     * @param {string | null} [arg0]
     */
    set topic(arg0) {
        var ptr0 = isLikeNone(arg0) ? 0 : passStringToWasm0(arg0, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
        var len0 = WASM_VECTOR_LEN;
        wasm.__wbg_set_outgoingmessage_topic(this.__wbg_ptr, ptr0, len0);
    }
}
if (Symbol.dispose) OutgoingMessage.prototype[Symbol.dispose] = OutgoingMessage.prototype.free;

/**
 * The main entry point for the Bitwarden SDK in WebAssembly environments
 */
class PasswordManagerClient {
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        PasswordManagerClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_passwordmanagerclient_free(ptr, 0);
    }
    /**
     * Auth related operations.
     * @returns {AuthClient}
     */
    auth() {
        const ret = wasm.passwordmanagerclient_auth(this.__wbg_ptr);
        return AuthClient.__wrap(ret);
    }
    /**
     * Bitwarden licensed operations.
     * @returns {CommercialPasswordManagerClient}
     */
    commercial() {
        const ret = wasm.passwordmanagerclient_commercial(this.__wbg_ptr);
        return CommercialPasswordManagerClient.__wrap(ret);
    }
    /**
     * Crypto related operations.
     * @returns {CryptoClient}
     */
    crypto() {
        const ret = wasm.passwordmanagerclient_crypto(this.__wbg_ptr);
        return CryptoClient.__wrap(ret);
    }
    /**
     * Test method, echoes back the input
     * @param {string} msg
     * @returns {string}
     */
    echo(msg) {
        let deferred2_0;
        let deferred2_1;
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passStringToWasm0(msg, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len0 = WASM_VECTOR_LEN;
            wasm.passwordmanagerclient_echo(retptr, this.__wbg_ptr, ptr0, len0);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            deferred2_0 = r0;
            deferred2_1 = r1;
            return getStringFromWasm0(r0, r1);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
            wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
        }
    }
    /**
     * Exporter related operations.
     * @returns {ExporterClient}
     */
    exporters() {
        const ret = wasm.passwordmanagerclient_exporters(this.__wbg_ptr);
        return ExporterClient.__wrap(ret);
    }
    /**
     * Constructs a specific client for generating passwords and passphrases
     * @returns {GeneratorClient}
     */
    generator() {
        const ret = wasm.passwordmanagerclient_generator(this.__wbg_ptr);
        return GeneratorClient.__wrap(ret);
    }
    /**
     * Test method, calls http endpoint
     * @param {string} url
     * @returns {Promise<string>}
     */
    http_get(url) {
        const ptr0 = passStringToWasm0(url, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.passwordmanagerclient_http_get(this.__wbg_ptr, ptr0, len0);
        return takeObject(ret);
    }
    /**
     * Initialize a new instance of the SDK client
     * @param {any} token_provider
     * @param {ClientSettings | null} [settings]
     */
    constructor(token_provider, settings) {
        const ret = wasm.passwordmanagerclient_new(addHeapObject(token_provider), isLikeNone(settings) ? 0 : addHeapObject(settings));
        this.__wbg_ptr = ret >>> 0;
        PasswordManagerClientFinalization.register(this, this.__wbg_ptr, this);
        return this;
    }
    /**
     * Constructs a specific client for platform-specific functionality
     * @returns {PlatformClient}
     */
    platform() {
        const ret = wasm.passwordmanagerclient_platform(this.__wbg_ptr);
        return PlatformClient.__wrap(ret);
    }
    /**
     * Send related operations.
     * @returns {SendClient}
     */
    sends() {
        const ret = wasm.passwordmanagerclient_sends(this.__wbg_ptr);
        return SendClient.__wrap(ret);
    }
    /**
     * Test method, always throws an error
     * @param {string} msg
     */
    throw(msg) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passStringToWasm0(msg, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len0 = WASM_VECTOR_LEN;
            wasm.passwordmanagerclient_throw(retptr, this.__wbg_ptr, ptr0, len0);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            if (r1) {
                throw takeObject(r0);
            }
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * User crypto management related operations.
     * @returns {UserCryptoManagementClient}
     */
    user_crypto_management() {
        const ret = wasm.passwordmanagerclient_user_crypto_management(this.__wbg_ptr);
        return UserCryptoManagementClient.__wrap(ret);
    }
    /**
     * Vault item related operations.
     * @returns {VaultClient}
     */
    vault() {
        const ret = wasm.passwordmanagerclient_vault(this.__wbg_ptr);
        return VaultClient.__wrap(ret);
    }
    /**
     * Returns the current SDK version
     * @returns {string}
     */
    version() {
        let deferred1_0;
        let deferred1_1;
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            wasm.passwordmanagerclient_version(retptr, this.__wbg_ptr);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            deferred1_0 = r0;
            deferred1_1 = r1;
            return getStringFromWasm0(r0, r1);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
            wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
        }
    }
}
if (Symbol.dispose) PasswordManagerClient.prototype[Symbol.dispose] = PasswordManagerClient.prototype.free;

class PlatformClient {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(PlatformClient.prototype);
        obj.__wbg_ptr = ptr;
        PlatformClientFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        PlatformClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_platformclient_free(ptr, 0);
    }
    /**
     * Load feature flags into the client
     * @param {FeatureFlags} flags
     * @returns {Promise<void>}
     */
    load_flags(flags) {
        const ret = wasm.platformclient_load_flags(this.__wbg_ptr, addHeapObject(flags));
        return takeObject(ret);
    }
    /**
     * @returns {StateClient}
     */
    state() {
        const ret = wasm.platformclient_state(this.__wbg_ptr);
        return StateClient.__wrap(ret);
    }
}
if (Symbol.dispose) PlatformClient.prototype[Symbol.dispose] = PlatformClient.prototype.free;

/**
 * This module represents a stopgap solution to provide access to primitive crypto functions for JS
 * clients. It is not intended to be used outside of the JS clients and this pattern should not be
 * proliferated. It is necessary because we want to use SDK crypto prior to the SDK being fully
 * responsible for state and keys.
 */
class PureCrypto {
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        PureCryptoFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_purecrypto_free(ptr, 0);
    }
    /**
     * Decapsulates (decrypts) a symmetric key using an decapsulation-key/private-key in PKCS8
     * DER format. Note: This is unsigned, so the sender's authenticity cannot be verified by the
     * recipient.
     * @param {string} encapsulated_key
     * @param {Uint8Array} decapsulation_key
     * @returns {Uint8Array}
     */
    static decapsulate_key_unsigned(encapsulated_key, decapsulation_key) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passStringToWasm0(encapsulated_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passArray8ToWasm0(decapsulation_key, wasm.__wbindgen_malloc);
            const len1 = WASM_VECTOR_LEN;
            wasm.purecrypto_decapsulate_key_unsigned(retptr, ptr0, len0, ptr1, len1);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            if (r3) {
                throw takeObject(r2);
            }
            var v3 = getArrayU8FromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 1, 1);
            return v3;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * @param {string} encrypted_user_key
     * @param {Uint8Array} master_key
     * @returns {Uint8Array}
     */
    static decrypt_user_key_with_master_key(encrypted_user_key, master_key) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passStringToWasm0(encrypted_user_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passArray8ToWasm0(master_key, wasm.__wbindgen_malloc);
            const len1 = WASM_VECTOR_LEN;
            wasm.purecrypto_decrypt_user_key_with_master_key(retptr, ptr0, len0, ptr1, len1);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            if (r3) {
                throw takeObject(r2);
            }
            var v3 = getArrayU8FromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 1, 1);
            return v3;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * @param {string} encrypted_user_key
     * @param {string} master_password
     * @param {string} email
     * @param {Kdf} kdf
     * @returns {Uint8Array}
     */
    static decrypt_user_key_with_master_password(encrypted_user_key, master_password, email, kdf) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passStringToWasm0(encrypted_user_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passStringToWasm0(master_password, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len1 = WASM_VECTOR_LEN;
            const ptr2 = passStringToWasm0(email, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len2 = WASM_VECTOR_LEN;
            wasm.purecrypto_decrypt_user_key_with_master_password(retptr, ptr0, len0, ptr1, len1, ptr2, len2, addHeapObject(kdf));
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            if (r3) {
                throw takeObject(r2);
            }
            var v4 = getArrayU8FromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 1, 1);
            return v4;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Derive output of the KDF for a [bitwarden_crypto::Kdf] configuration.
     * @param {Uint8Array} password
     * @param {Uint8Array} salt
     * @param {Kdf} kdf
     * @returns {Uint8Array}
     */
    static derive_kdf_material(password, salt, kdf) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passArray8ToWasm0(password, wasm.__wbindgen_malloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passArray8ToWasm0(salt, wasm.__wbindgen_malloc);
            const len1 = WASM_VECTOR_LEN;
            wasm.purecrypto_derive_kdf_material(retptr, ptr0, len0, ptr1, len1, addHeapObject(kdf));
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            if (r3) {
                throw takeObject(r2);
            }
            var v3 = getArrayU8FromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 1, 1);
            return v3;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Encapsulates (encrypts) a symmetric key using an public-key/encapsulation-key
     * in SPKI format, returning the encapsulated key as a string. Note: This is unsigned, so
     * the sender's authenticity cannot be verified by the recipient.
     * @param {Uint8Array} shared_key
     * @param {Uint8Array} encapsulation_key
     * @returns {string}
     */
    static encapsulate_key_unsigned(shared_key, encapsulation_key) {
        let deferred4_0;
        let deferred4_1;
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passArray8ToWasm0(shared_key, wasm.__wbindgen_malloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passArray8ToWasm0(encapsulation_key, wasm.__wbindgen_malloc);
            const len1 = WASM_VECTOR_LEN;
            wasm.purecrypto_encapsulate_key_unsigned(retptr, ptr0, len0, ptr1, len1);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            var ptr3 = r0;
            var len3 = r1;
            if (r3) {
                ptr3 = 0; len3 = 0;
                throw takeObject(r2);
            }
            deferred4_0 = ptr3;
            deferred4_1 = len3;
            return getStringFromWasm0(ptr3, len3);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
            wasm.__wbindgen_free(deferred4_0, deferred4_1, 1);
        }
    }
    /**
     * @param {Uint8Array} user_key
     * @param {string} master_password
     * @param {string} email
     * @param {Kdf} kdf
     * @returns {string}
     */
    static encrypt_user_key_with_master_password(user_key, master_password, email, kdf) {
        let deferred5_0;
        let deferred5_1;
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passArray8ToWasm0(user_key, wasm.__wbindgen_malloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passStringToWasm0(master_password, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len1 = WASM_VECTOR_LEN;
            const ptr2 = passStringToWasm0(email, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len2 = WASM_VECTOR_LEN;
            wasm.purecrypto_encrypt_user_key_with_master_password(retptr, ptr0, len0, ptr1, len1, ptr2, len2, addHeapObject(kdf));
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            var ptr4 = r0;
            var len4 = r1;
            if (r3) {
                ptr4 = 0; len4 = 0;
                throw takeObject(r2);
            }
            deferred5_0 = ptr4;
            deferred5_1 = len4;
            return getStringFromWasm0(ptr4, len4);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
            wasm.__wbindgen_free(deferred5_0, deferred5_1, 1);
        }
    }
    /**
     * Returns the algorithm used for the given verifying key.
     * @param {Uint8Array} verifying_key
     * @returns {SignatureAlgorithm}
     */
    static key_algorithm_for_verifying_key(verifying_key) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passArray8ToWasm0(verifying_key, wasm.__wbindgen_malloc);
            const len0 = WASM_VECTOR_LEN;
            wasm.purecrypto_key_algorithm_for_verifying_key(retptr, ptr0, len0);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            if (r2) {
                throw takeObject(r1);
            }
            return takeObject(r0);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * @returns {Uint8Array}
     */
    static make_user_key_aes256_cbc_hmac() {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            wasm.purecrypto_make_user_key_aes256_cbc_hmac(retptr);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var v1 = getArrayU8FromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 1, 1);
            return v1;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * @returns {Uint8Array}
     */
    static make_user_key_xchacha20_poly1305() {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            wasm.purecrypto_make_user_key_xchacha20_poly1305(retptr);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var v1 = getArrayU8FromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 1, 1);
            return v1;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Generates a cryptographically secure random number between the given min and max
     * (inclusive).
     * @param {number} min
     * @param {number} max
     * @returns {number}
     */
    static random_number(min, max) {
        const ret = wasm.purecrypto_random_number(min, max);
        return ret >>> 0;
    }
    /**
     * Decrypts data using RSAES-OAEP with SHA-1
     * HAZMAT WARNING: Do not use outside of implementing cryptofunctionservice
     * @param {Uint8Array} encrypted_data
     * @param {Uint8Array} private_key
     * @returns {Uint8Array}
     */
    static rsa_decrypt_data(encrypted_data, private_key) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passArray8ToWasm0(encrypted_data, wasm.__wbindgen_malloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passArray8ToWasm0(private_key, wasm.__wbindgen_malloc);
            const len1 = WASM_VECTOR_LEN;
            wasm.purecrypto_rsa_decrypt_data(retptr, ptr0, len0, ptr1, len1);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            if (r3) {
                throw takeObject(r2);
            }
            var v3 = getArrayU8FromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 1, 1);
            return v3;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Encrypts data using RSAES-OAEP with SHA-1
     * HAZMAT WARNING: Do not use outside of implementing cryptofunctionservice
     * @param {Uint8Array} plain_data
     * @param {Uint8Array} public_key
     * @returns {Uint8Array}
     */
    static rsa_encrypt_data(plain_data, public_key) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passArray8ToWasm0(plain_data, wasm.__wbindgen_malloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passArray8ToWasm0(public_key, wasm.__wbindgen_malloc);
            const len1 = WASM_VECTOR_LEN;
            wasm.purecrypto_rsa_encrypt_data(retptr, ptr0, len0, ptr1, len1);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            if (r3) {
                throw takeObject(r2);
            }
            var v3 = getArrayU8FromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 1, 1);
            return v3;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Given a decrypted private RSA key PKCS8 DER this
     * returns the corresponding public RSA key in DER format.
     * HAZMAT WARNING: Do not use outside of implementing cryptofunctionservice
     * @param {Uint8Array} private_key
     * @returns {Uint8Array}
     */
    static rsa_extract_public_key(private_key) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passArray8ToWasm0(private_key, wasm.__wbindgen_malloc);
            const len0 = WASM_VECTOR_LEN;
            wasm.purecrypto_rsa_extract_public_key(retptr, ptr0, len0);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            if (r3) {
                throw takeObject(r2);
            }
            var v2 = getArrayU8FromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 1, 1);
            return v2;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Generates a new RSA key pair and returns the private key
     * HAZMAT WARNING: Do not use outside of implementing cryptofunctionservice
     * @returns {Uint8Array}
     */
    static rsa_generate_keypair() {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            wasm.purecrypto_rsa_generate_keypair(retptr);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            if (r3) {
                throw takeObject(r2);
            }
            var v1 = getArrayU8FromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 1, 1);
            return v1;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * DEPRECATED: Use `symmetric_decrypt_string` instead.
     * Cleanup ticket: <https://bitwarden.atlassian.net/browse/PM-21247>
     * @param {string} enc_string
     * @param {Uint8Array} key
     * @returns {string}
     */
    static symmetric_decrypt(enc_string, key) {
        let deferred4_0;
        let deferred4_1;
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passStringToWasm0(enc_string, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passArray8ToWasm0(key, wasm.__wbindgen_malloc);
            const len1 = WASM_VECTOR_LEN;
            wasm.purecrypto_symmetric_decrypt(retptr, ptr0, len0, ptr1, len1);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            var ptr3 = r0;
            var len3 = r1;
            if (r3) {
                ptr3 = 0; len3 = 0;
                throw takeObject(r2);
            }
            deferred4_0 = ptr3;
            deferred4_1 = len3;
            return getStringFromWasm0(ptr3, len3);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
            wasm.__wbindgen_free(deferred4_0, deferred4_1, 1);
        }
    }
    /**
     * DEPRECATED: Use `symmetric_decrypt_filedata` instead.
     * Cleanup ticket: <https://bitwarden.atlassian.net/browse/PM-21247>
     * @param {Uint8Array} enc_bytes
     * @param {Uint8Array} key
     * @returns {Uint8Array}
     */
    static symmetric_decrypt_array_buffer(enc_bytes, key) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passArray8ToWasm0(enc_bytes, wasm.__wbindgen_malloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passArray8ToWasm0(key, wasm.__wbindgen_malloc);
            const len1 = WASM_VECTOR_LEN;
            wasm.purecrypto_symmetric_decrypt_array_buffer(retptr, ptr0, len0, ptr1, len1);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            if (r3) {
                throw takeObject(r2);
            }
            var v3 = getArrayU8FromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 1, 1);
            return v3;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * @param {string} enc_string
     * @param {Uint8Array} key
     * @returns {Uint8Array}
     */
    static symmetric_decrypt_bytes(enc_string, key) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passStringToWasm0(enc_string, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passArray8ToWasm0(key, wasm.__wbindgen_malloc);
            const len1 = WASM_VECTOR_LEN;
            wasm.purecrypto_symmetric_decrypt_bytes(retptr, ptr0, len0, ptr1, len1);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            if (r3) {
                throw takeObject(r2);
            }
            var v3 = getArrayU8FromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 1, 1);
            return v3;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * @param {Uint8Array} enc_bytes
     * @param {Uint8Array} key
     * @returns {Uint8Array}
     */
    static symmetric_decrypt_filedata(enc_bytes, key) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passArray8ToWasm0(enc_bytes, wasm.__wbindgen_malloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passArray8ToWasm0(key, wasm.__wbindgen_malloc);
            const len1 = WASM_VECTOR_LEN;
            wasm.purecrypto_symmetric_decrypt_filedata(retptr, ptr0, len0, ptr1, len1);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            if (r3) {
                throw takeObject(r2);
            }
            var v3 = getArrayU8FromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 1, 1);
            return v3;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * @param {string} enc_string
     * @param {Uint8Array} key
     * @returns {string}
     */
    static symmetric_decrypt_string(enc_string, key) {
        let deferred4_0;
        let deferred4_1;
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passStringToWasm0(enc_string, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passArray8ToWasm0(key, wasm.__wbindgen_malloc);
            const len1 = WASM_VECTOR_LEN;
            wasm.purecrypto_symmetric_decrypt_string(retptr, ptr0, len0, ptr1, len1);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            var ptr3 = r0;
            var len3 = r1;
            if (r3) {
                ptr3 = 0; len3 = 0;
                throw takeObject(r2);
            }
            deferred4_0 = ptr3;
            deferred4_1 = len3;
            return getStringFromWasm0(ptr3, len3);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
            wasm.__wbindgen_free(deferred4_0, deferred4_1, 1);
        }
    }
    /**
     * DEPRECATED: Only used by send keys
     * @param {Uint8Array} plain
     * @param {Uint8Array} key
     * @returns {string}
     */
    static symmetric_encrypt_bytes(plain, key) {
        let deferred4_0;
        let deferred4_1;
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passArray8ToWasm0(plain, wasm.__wbindgen_malloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passArray8ToWasm0(key, wasm.__wbindgen_malloc);
            const len1 = WASM_VECTOR_LEN;
            wasm.purecrypto_symmetric_encrypt_bytes(retptr, ptr0, len0, ptr1, len1);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            var ptr3 = r0;
            var len3 = r1;
            if (r3) {
                ptr3 = 0; len3 = 0;
                throw takeObject(r2);
            }
            deferred4_0 = ptr3;
            deferred4_1 = len3;
            return getStringFromWasm0(ptr3, len3);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
            wasm.__wbindgen_free(deferred4_0, deferred4_1, 1);
        }
    }
    /**
     * @param {Uint8Array} plain
     * @param {Uint8Array} key
     * @returns {Uint8Array}
     */
    static symmetric_encrypt_filedata(plain, key) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passArray8ToWasm0(plain, wasm.__wbindgen_malloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passArray8ToWasm0(key, wasm.__wbindgen_malloc);
            const len1 = WASM_VECTOR_LEN;
            wasm.purecrypto_symmetric_encrypt_filedata(retptr, ptr0, len0, ptr1, len1);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            if (r3) {
                throw takeObject(r2);
            }
            var v3 = getArrayU8FromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 1, 1);
            return v3;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * @param {string} plain
     * @param {Uint8Array} key
     * @returns {string}
     */
    static symmetric_encrypt_string(plain, key) {
        let deferred4_0;
        let deferred4_1;
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passStringToWasm0(plain, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passArray8ToWasm0(key, wasm.__wbindgen_malloc);
            const len1 = WASM_VECTOR_LEN;
            wasm.purecrypto_symmetric_encrypt_string(retptr, ptr0, len0, ptr1, len1);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            var ptr3 = r0;
            var len3 = r1;
            if (r3) {
                ptr3 = 0; len3 = 0;
                throw takeObject(r2);
            }
            deferred4_0 = ptr3;
            deferred4_1 = len3;
            return getStringFromWasm0(ptr3, len3);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
            wasm.__wbindgen_free(deferred4_0, deferred4_1, 1);
        }
    }
    /**
     * Unwraps (decrypts) a wrapped PKCS8 DER encoded decapsulation (private) key using a symmetric
     * wrapping key.
     * @param {string} wrapped_key
     * @param {Uint8Array} wrapping_key
     * @returns {Uint8Array}
     */
    static unwrap_decapsulation_key(wrapped_key, wrapping_key) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passStringToWasm0(wrapped_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passArray8ToWasm0(wrapping_key, wasm.__wbindgen_malloc);
            const len1 = WASM_VECTOR_LEN;
            wasm.purecrypto_unwrap_decapsulation_key(retptr, ptr0, len0, ptr1, len1);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            if (r3) {
                throw takeObject(r2);
            }
            var v3 = getArrayU8FromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 1, 1);
            return v3;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Unwraps (decrypts) a wrapped SPKI DER encoded encapsulation (public) key using a symmetric
     * wrapping key.
     * @param {string} wrapped_key
     * @param {Uint8Array} wrapping_key
     * @returns {Uint8Array}
     */
    static unwrap_encapsulation_key(wrapped_key, wrapping_key) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passStringToWasm0(wrapped_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passArray8ToWasm0(wrapping_key, wasm.__wbindgen_malloc);
            const len1 = WASM_VECTOR_LEN;
            wasm.purecrypto_unwrap_encapsulation_key(retptr, ptr0, len0, ptr1, len1);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            if (r3) {
                throw takeObject(r2);
            }
            var v3 = getArrayU8FromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 1, 1);
            return v3;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Unwraps (decrypts) a wrapped symmetric key using a symmetric wrapping key, returning the
     * unwrapped key as a serialized byte array.
     * @param {string} wrapped_key
     * @param {Uint8Array} wrapping_key
     * @returns {Uint8Array}
     */
    static unwrap_symmetric_key(wrapped_key, wrapping_key) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passStringToWasm0(wrapped_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passArray8ToWasm0(wrapping_key, wasm.__wbindgen_malloc);
            const len1 = WASM_VECTOR_LEN;
            wasm.purecrypto_unwrap_symmetric_key(retptr, ptr0, len0, ptr1, len1);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            if (r3) {
                throw takeObject(r2);
            }
            var v3 = getArrayU8FromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 1, 1);
            return v3;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * For a given signing identity (verifying key), this function verifies that the signing
     * identity claimed ownership of the public key. This is a one-sided claim and merely shows
     * that the signing identity has the intent to receive messages encrypted to the public
     * key.
     * @param {Uint8Array} signed_public_key
     * @param {Uint8Array} verifying_key
     * @returns {Uint8Array}
     */
    static verify_and_unwrap_signed_public_key(signed_public_key, verifying_key) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passArray8ToWasm0(signed_public_key, wasm.__wbindgen_malloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passArray8ToWasm0(verifying_key, wasm.__wbindgen_malloc);
            const len1 = WASM_VECTOR_LEN;
            wasm.purecrypto_verify_and_unwrap_signed_public_key(retptr, ptr0, len0, ptr1, len1);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            if (r3) {
                throw takeObject(r2);
            }
            var v3 = getArrayU8FromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 1, 1);
            return v3;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Given a wrapped signing key and the symmetric key it is wrapped with, this returns
     * the corresponding verifying key.
     * @param {string} signing_key
     * @param {Uint8Array} wrapping_key
     * @returns {Uint8Array}
     */
    static verifying_key_for_signing_key(signing_key, wrapping_key) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passStringToWasm0(signing_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passArray8ToWasm0(wrapping_key, wasm.__wbindgen_malloc);
            const len1 = WASM_VECTOR_LEN;
            wasm.purecrypto_verifying_key_for_signing_key(retptr, ptr0, len0, ptr1, len1);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            if (r3) {
                throw takeObject(r2);
            }
            var v3 = getArrayU8FromWasm0(r0, r1).slice();
            wasm.__wbindgen_free(r0, r1 * 1, 1);
            return v3;
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
    /**
     * Wraps (encrypts) a PKCS8 DER encoded decapsulation (private) key using a symmetric wrapping
     * key,
     * @param {Uint8Array} decapsulation_key
     * @param {Uint8Array} wrapping_key
     * @returns {string}
     */
    static wrap_decapsulation_key(decapsulation_key, wrapping_key) {
        let deferred4_0;
        let deferred4_1;
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passArray8ToWasm0(decapsulation_key, wasm.__wbindgen_malloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passArray8ToWasm0(wrapping_key, wasm.__wbindgen_malloc);
            const len1 = WASM_VECTOR_LEN;
            wasm.purecrypto_wrap_decapsulation_key(retptr, ptr0, len0, ptr1, len1);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            var ptr3 = r0;
            var len3 = r1;
            if (r3) {
                ptr3 = 0; len3 = 0;
                throw takeObject(r2);
            }
            deferred4_0 = ptr3;
            deferred4_1 = len3;
            return getStringFromWasm0(ptr3, len3);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
            wasm.__wbindgen_free(deferred4_0, deferred4_1, 1);
        }
    }
    /**
     * Wraps (encrypts) an SPKI DER encoded encapsulation (public) key using a symmetric wrapping
     * key. Note: Usually, a public key is - by definition - public, so this should not be
     * used. The specific use-case for this function is to enable rotateable key sets, where
     * the "public key" is not public, with the intent of preventing the server from being able
     * to overwrite the user key unlocked by the rotateable keyset.
     * @param {Uint8Array} encapsulation_key
     * @param {Uint8Array} wrapping_key
     * @returns {string}
     */
    static wrap_encapsulation_key(encapsulation_key, wrapping_key) {
        let deferred4_0;
        let deferred4_1;
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passArray8ToWasm0(encapsulation_key, wasm.__wbindgen_malloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passArray8ToWasm0(wrapping_key, wasm.__wbindgen_malloc);
            const len1 = WASM_VECTOR_LEN;
            wasm.purecrypto_wrap_encapsulation_key(retptr, ptr0, len0, ptr1, len1);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            var ptr3 = r0;
            var len3 = r1;
            if (r3) {
                ptr3 = 0; len3 = 0;
                throw takeObject(r2);
            }
            deferred4_0 = ptr3;
            deferred4_1 = len3;
            return getStringFromWasm0(ptr3, len3);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
            wasm.__wbindgen_free(deferred4_0, deferred4_1, 1);
        }
    }
    /**
     * Wraps (encrypts) a symmetric key using a symmetric wrapping key, returning the wrapped key
     * as an EncString.
     * @param {Uint8Array} key_to_be_wrapped
     * @param {Uint8Array} wrapping_key
     * @returns {string}
     */
    static wrap_symmetric_key(key_to_be_wrapped, wrapping_key) {
        let deferred4_0;
        let deferred4_1;
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passArray8ToWasm0(key_to_be_wrapped, wasm.__wbindgen_malloc);
            const len0 = WASM_VECTOR_LEN;
            const ptr1 = passArray8ToWasm0(wrapping_key, wasm.__wbindgen_malloc);
            const len1 = WASM_VECTOR_LEN;
            wasm.purecrypto_wrap_symmetric_key(retptr, ptr0, len0, ptr1, len1);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
            var ptr3 = r0;
            var len3 = r1;
            if (r3) {
                ptr3 = 0; len3 = 0;
                throw takeObject(r2);
            }
            deferred4_0 = ptr3;
            deferred4_1 = len3;
            return getStringFromWasm0(ptr3, len3);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
            wasm.__wbindgen_free(deferred4_0, deferred4_1, 1);
        }
    }
}
if (Symbol.dispose) PureCrypto.prototype[Symbol.dispose] = PureCrypto.prototype.free;

/**
 * Client for initializing a user account.
 */
class RegistrationClient {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(RegistrationClient.prototype);
        obj.__wbg_ptr = ptr;
        RegistrationClientFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        RegistrationClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_registrationclient_free(ptr, 0);
    }
    /**
     * Initializes a new cryptographic state for a user and posts it to the server;
     * enrolls the user to master password unlock.
     * @param {JitMasterPasswordRegistrationRequest} request
     * @returns {Promise<JitMasterPasswordRegistrationResponse>}
     */
    post_keys_for_jit_password_registration(request) {
        const ret = wasm.registrationclient_post_keys_for_jit_password_registration(this.__wbg_ptr, addHeapObject(request));
        return takeObject(ret);
    }
    /**
     * Initializes a new cryptographic state for a user and posts it to the server; enrolls the
     * user to key connector unlock.
     * @param {string} key_connector_url
     * @param {string} sso_org_identifier
     * @returns {Promise<KeyConnectorRegistrationResult>}
     */
    post_keys_for_key_connector_registration(key_connector_url, sso_org_identifier) {
        const ptr0 = passStringToWasm0(key_connector_url, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
        const len0 = WASM_VECTOR_LEN;
        const ptr1 = passStringToWasm0(sso_org_identifier, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
        const len1 = WASM_VECTOR_LEN;
        const ret = wasm.registrationclient_post_keys_for_key_connector_registration(this.__wbg_ptr, ptr0, len0, ptr1, len1);
        return takeObject(ret);
    }
    /**
     * Initializes a new cryptographic state for a user and posts it to the server; enrolls in
     * admin password reset and finally enrolls the user to TDE unlock.
     * @param {TdeRegistrationRequest} request
     * @returns {Promise<TdeRegistrationResponse>}
     */
    post_keys_for_tde_registration(request) {
        const ret = wasm.registrationclient_post_keys_for_tde_registration(this.__wbg_ptr, addHeapObject(request));
        return takeObject(ret);
    }
}
if (Symbol.dispose) RegistrationClient.prototype[Symbol.dispose] = RegistrationClient.prototype.free;

/**
 * @enum {0 | 1 | 2 | 3}
 */
const RsaError = Object.freeze({
    Decryption: 0, "0": "Decryption",
    Encryption: 1, "1": "Encryption",
    KeyParse: 2, "2": "KeyParse",
    KeySerialize: 3, "3": "KeySerialize",
});

/**
 * @enum {0}
 */
const SecureNoteType = Object.freeze({
    Generic: 0, "0": "Generic",
});

/**
 * The `SendAccessClient` is used to interact with the Bitwarden API to get send access tokens.
 */
class SendAccessClient {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(SendAccessClient.prototype);
        obj.__wbg_ptr = ptr;
        SendAccessClientFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        SendAccessClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_sendaccessclient_free(ptr, 0);
    }
    /**
     * Requests a new send access token.
     * @param {SendAccessTokenRequest} request
     * @returns {Promise<SendAccessTokenResponse>}
     */
    request_send_access_token(request) {
        const ret = wasm.sendaccessclient_request_send_access_token(this.__wbg_ptr, addHeapObject(request));
        return takeObject(ret);
    }
}
if (Symbol.dispose) SendAccessClient.prototype[Symbol.dispose] = SendAccessClient.prototype.free;

class SendClient {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(SendClient.prototype);
        obj.__wbg_ptr = ptr;
        SendClientFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        SendClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_sendclient_free(ptr, 0);
    }
    /**
     * Create a new [Send] and save it to the server.
     * @param {SendAddRequest} request
     * @returns {Promise<SendView>}
     */
    create(request) {
        const ret = wasm.sendclient_create(this.__wbg_ptr, addHeapObject(request));
        return takeObject(ret);
    }
    /**
     * Edit the [Send] and save it to the server.
     * @param {SendId} send_id
     * @param {SendEditRequest} request
     * @returns {Promise<SendView>}
     */
    edit(send_id, request) {
        const ret = wasm.sendclient_edit(this.__wbg_ptr, addHeapObject(send_id), addHeapObject(request));
        return takeObject(ret);
    }
    /**
     * Get a specific [Send] by its ID from state and decrypt it to a [SendView].
     * @param {SendId} send_id
     * @returns {Promise<SendView>}
     */
    get(send_id) {
        const ret = wasm.sendclient_get(this.__wbg_ptr, addHeapObject(send_id));
        return takeObject(ret);
    }
    /**
     * Get all sends from state and decrypt them to a list of [SendView].
     * @returns {Promise<SendView[]>}
     */
    list() {
        const ret = wasm.sendclient_list(this.__wbg_ptr);
        return takeObject(ret);
    }
}
if (Symbol.dispose) SendClient.prototype[Symbol.dispose] = SendClient.prototype.free;

/**
 * JavaScript wrapper for ServerCommunicationConfigClient
 *
 * This provides TypeScript access to the server communication configuration client,
 * allowing clients to check bootstrap requirements and retrieve cookies for HTTP requests.
 */
class ServerCommunicationConfigClient {
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        ServerCommunicationConfigClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_servercommunicationconfigclient_free(ptr, 0);
    }
    /**
     * Acquires a cookie from the platform and saves it to the repository
     *
     * This method calls the platform API to trigger cookie acquisition (e.g., browser
     * redirect to IdP), then validates and stores the acquired cookie in the repository.
     *
     * # Arguments
     *
     * * `hostname` - The server hostname (e.g., "vault.acme.com")
     *
     * # Errors
     *
     * Returns an error if:
     * - Cookie acquisition was cancelled by the user
     * - Server configuration doesn't support SSO cookies (Direct bootstrap)
     * - Acquired cookie name doesn't match expected name
     * - Repository operations fail
     * @param {string} hostname
     * @returns {Promise<void>}
     */
    acquireCookie(hostname) {
        const ptr0 = passStringToWasm0(hostname, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.servercommunicationconfigclient_acquireCookie(this.__wbg_ptr, ptr0, len0);
        return takeObject(ret);
    }
    /**
     * Returns all cookies that should be included in requests to this server
     *
     * Returns an array of [cookie_name, cookie_value] pairs.
     *
     * # Arguments
     *
     * * `hostname` - The server hostname (e.g., "vault.acme.com")
     * @param {string} hostname
     * @returns {Promise<any>}
     */
    cookies(hostname) {
        const ptr0 = passStringToWasm0(hostname, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.servercommunicationconfigclient_cookies(this.__wbg_ptr, ptr0, len0);
        return takeObject(ret);
    }
    /**
     * Retrieves the server communication configuration for a hostname
     *
     * If no configuration exists, returns a default Direct bootstrap configuration.
     *
     * # Arguments
     *
     * * `hostname` - The server hostname (e.g., "vault.acme.com")
     *
     * # Errors
     *
     * Returns an error if the repository fails to retrieve the configuration.
     * @param {string} hostname
     * @returns {Promise<ServerCommunicationConfig>}
     */
    getConfig(hostname) {
        const ptr0 = passStringToWasm0(hostname, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.servercommunicationconfigclient_getConfig(this.__wbg_ptr, ptr0, len0);
        return takeObject(ret);
    }
    /**
     * Determines if cookie bootstrapping is needed for this hostname
     *
     * # Arguments
     *
     * * `hostname` - The server hostname (e.g., "vault.acme.com")
     * @param {string} hostname
     * @returns {Promise<boolean>}
     */
    needsBootstrap(hostname) {
        const ptr0 = passStringToWasm0(hostname, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.servercommunicationconfigclient_needsBootstrap(this.__wbg_ptr, ptr0, len0);
        return takeObject(ret);
    }
    /**
     * Creates a new ServerCommunicationConfigClient with a JavaScript repository and platform API
     *
     * The repository should be backed by StateProvider (or equivalent
     * storage mechanism) for persistence.
     *
     * # Arguments
     *
     * * `repository` - JavaScript implementation of the repository interface
     * * `platform_api` - JavaScript implementation of the platform API interface
     * @param {ServerCommunicationConfigRepository} repository
     * @param {ServerCommunicationConfigPlatformApi} platform_api
     */
    constructor(repository, platform_api) {
        const ret = wasm.servercommunicationconfigclient_new(addHeapObject(repository), addHeapObject(platform_api));
        this.__wbg_ptr = ret >>> 0;
        ServerCommunicationConfigClientFinalization.register(this, this.__wbg_ptr, this);
        return this;
    }
    /**
     * Sets the server communication configuration for a hostname
     *
     * This method saves the provided communication configuration to the repository.
     * Typically called when receiving the `/api/config` response from the server.
     * Previously acquired cookies are preserved automatically.
     *
     * # Arguments
     *
     * * `hostname` - The server hostname (e.g., "vault.acme.com")
     * * `request` - The server communication configuration to store
     *
     * # Errors
     *
     * Returns an error if the repository save operation fails
     * @param {string} hostname
     * @param {SetCommunicationTypeRequest} request
     * @returns {Promise<void>}
     */
    setCommunicationType(hostname, request) {
        const ptr0 = passStringToWasm0(hostname, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.servercommunicationconfigclient_setCommunicationType(this.__wbg_ptr, ptr0, len0, addHeapObject(request));
        return takeObject(ret);
    }
}
if (Symbol.dispose) ServerCommunicationConfigClient.prototype[Symbol.dispose] = ServerCommunicationConfigClient.prototype.free;

class StateClient {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(StateClient.prototype);
        obj.__wbg_ptr = ptr;
        StateClientFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        StateClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_stateclient_free(ptr, 0);
    }
    /**
     * @param {any} cipher_repository
     */
    register_cipher_repository(cipher_repository) {
        wasm.stateclient_register_cipher_repository(this.__wbg_ptr, addHeapObject(cipher_repository));
    }
    /**
     * @param {Repositories} repositories
     */
    register_client_managed_repositories(repositories) {
        wasm.stateclient_register_client_managed_repositories(this.__wbg_ptr, addHeapObject(repositories));
    }
    /**
     * @param {any} store
     */
    register_folder_repository(store) {
        wasm.stateclient_register_folder_repository(this.__wbg_ptr, addHeapObject(store));
    }
}
if (Symbol.dispose) StateClient.prototype[Symbol.dispose] = StateClient.prototype.free;

class TotpClient {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(TotpClient.prototype);
        obj.__wbg_ptr = ptr;
        TotpClientFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        TotpClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_totpclient_free(ptr, 0);
    }
    /**
     * Generates a TOTP code from a provided key
     *
     * # Arguments
     * - `key` - Can be:
     *     - A base32 encoded string
     *     - OTP Auth URI
     *     - Steam URI
     * - `time_ms` - Optional timestamp in milliseconds
     * @param {string} key
     * @param {number | null} [time_ms]
     * @returns {TotpResponse}
     */
    generate_totp(key, time_ms) {
        try {
            const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
            const ptr0 = passStringToWasm0(key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
            const len0 = WASM_VECTOR_LEN;
            wasm.totpclient_generate_totp(retptr, this.__wbg_ptr, ptr0, len0, !isLikeNone(time_ms), isLikeNone(time_ms) ? 0 : time_ms);
            var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
            var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
            var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
            if (r2) {
                throw takeObject(r1);
            }
            return takeObject(r0);
        } finally {
            wasm.__wbindgen_add_to_stack_pointer(16);
        }
    }
}
if (Symbol.dispose) TotpClient.prototype[Symbol.dispose] = TotpClient.prototype.free;

/**
 * @enum {0 | 1 | 2 | 3 | 4 | 5}
 */
const UriMatchType = Object.freeze({
    Domain: 0, "0": "Domain",
    Host: 1, "1": "Host",
    StartsWith: 2, "2": "StartsWith",
    Exact: 3, "3": "Exact",
    RegularExpression: 4, "4": "RegularExpression",
    Never: 5, "5": "Never",
});

/**
 * Client for managing the cryptographic machinery of a user account, including key-rotation.
 */
class UserCryptoManagementClient {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(UserCryptoManagementClient.prototype);
        obj.__wbg_ptr = ptr;
        UserCryptoManagementClientFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        UserCryptoManagementClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_usercryptomanagementclient_free(ptr, 0);
    }
    /**
     * Fetches the emergency access public keys for V1 emergency access memberships for the user.
     * These have to be trusted manually be the user before rotating.
     * @returns {Promise<V1EmergencyAccessMembership[]>}
     */
    get_untrusted_emergency_access_public_keys() {
        const ret = wasm.usercryptomanagementclient_get_untrusted_emergency_access_public_keys(this.__wbg_ptr);
        return takeObject(ret);
    }
    /**
     * Fetches the organization public keys for V1 organization memberships for the user for
     * organizations for which reset password is enrolled.
     * These have to be trusted manually be the user before rotating.
     * @returns {Promise<V1OrganizationMembership[]>}
     */
    get_untrusted_organization_public_keys() {
        const ret = wasm.usercryptomanagementclient_get_untrusted_organization_public_keys(this.__wbg_ptr);
        return takeObject(ret);
    }
    /**
     * Migrates an initialized account to Key Connector unlock.
     *
     * Requires the client to be unlocked so the current user key is available in memory.
     * @param {string} key_connector_url
     * @returns {Promise<void>}
     */
    migrate_to_key_connector(key_connector_url) {
        const ptr0 = passStringToWasm0(key_connector_url, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
        const len0 = WASM_VECTOR_LEN;
        const ret = wasm.usercryptomanagementclient_migrate_to_key_connector(this.__wbg_ptr, ptr0, len0);
        return takeObject(ret);
    }
    /**
     * Combines a password change and user key rotation into a single request.
     * @param {PasswordChangeAndRotateUserKeysRequest} request
     * @returns {Promise<void>}
     */
    password_change_and_rotate_user_keys(request) {
        const ret = wasm.usercryptomanagementclient_password_change_and_rotate_user_keys(this.__wbg_ptr, addHeapObject(request));
        return takeObject(ret);
    }
}
if (Symbol.dispose) UserCryptoManagementClient.prototype[Symbol.dispose] = UserCryptoManagementClient.prototype.free;

class VaultClient {
    static __wrap(ptr) {
        ptr = ptr >>> 0;
        const obj = Object.create(VaultClient.prototype);
        obj.__wbg_ptr = ptr;
        VaultClientFinalization.register(obj, obj.__wbg_ptr, obj);
        return obj;
    }
    __destroy_into_raw() {
        const ptr = this.__wbg_ptr;
        this.__wbg_ptr = 0;
        VaultClientFinalization.unregister(this);
        return ptr;
    }
    free() {
        const ptr = this.__destroy_into_raw();
        wasm.__wbg_vaultclient_free(ptr, 0);
    }
    /**
     * Attachment related operations.
     * @returns {AttachmentsClient}
     */
    attachments() {
        const ret = wasm.vaultclient_attachments(this.__wbg_ptr);
        return AttachmentsClient.__wrap(ret);
    }
    /**
     * Cipher risk evaluation operations.
     * @returns {CipherRiskClient}
     */
    cipher_risk() {
        const ret = wasm.vaultclient_cipher_risk(this.__wbg_ptr);
        return CipherRiskClient.__wrap(ret);
    }
    /**
     * Cipher related operations.
     * @returns {CiphersClient}
     */
    ciphers() {
        const ret = wasm.vaultclient_ciphers(this.__wbg_ptr);
        return CiphersClient.__wrap(ret);
    }
    /**
     * Collection related operations.
     * @returns {CollectionsClient}
     */
    collections() {
        const ret = wasm.vaultclient_collections(this.__wbg_ptr);
        return CollectionsClient.__wrap(ret);
    }
    /**
     * Folder related operations.
     * @returns {FoldersClient}
     */
    folders() {
        const ret = wasm.vaultclient_folders(this.__wbg_ptr);
        return FoldersClient.__wrap(ret);
    }
    /**
     * TOTP related operations.
     * @returns {TotpClient}
     */
    totp() {
        const ret = wasm.vaultclient_totp(this.__wbg_ptr);
        return TotpClient.__wrap(ret);
    }
}
if (Symbol.dispose) VaultClient.prototype[Symbol.dispose] = VaultClient.prototype.free;

/**
 * Generate a new SSH key pair
 *
 * # Arguments
 * - `key_algorithm` - The algorithm to use for the key pair
 *
 * # Returns
 * - `Ok(SshKey)` if the key was successfully generated
 * - `Err(KeyGenerationError)` if the key could not be generated
 * @param {KeyAlgorithm} key_algorithm
 * @returns {SshKeyView}
 */
function generate_ssh_key(key_algorithm) {
    try {
        const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
        wasm.generate_ssh_key(retptr, addHeapObject(key_algorithm));
        var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
        var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
        var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
        if (r2) {
            throw takeObject(r1);
        }
        return takeObject(r0);
    } finally {
        wasm.__wbindgen_add_to_stack_pointer(16);
    }
}

/**
 * Convert a PCKS8 or OpenSSH encrypted or unencrypted private key
 * to an OpenSSH private key with public key and fingerprint
 *
 * # Arguments
 * - `imported_key` - The private key to convert
 * - `password` - The password to use for decrypting the key
 *
 * # Returns
 * - `Ok(SshKey)` if the key was successfully coneverted
 * - `Err(PasswordRequired)` if the key is encrypted and no password was provided
 * - `Err(WrongPassword)` if the password provided is incorrect
 * - `Err(ParsingError)` if the key could not be parsed
 * - `Err(UnsupportedKeyType)` if the key type is not supported
 * @param {string} imported_key
 * @param {string | null} [password]
 * @returns {SshKeyView}
 */
function import_ssh_key(imported_key, password) {
    try {
        const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
        const ptr0 = passStringToWasm0(imported_key, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
        const len0 = WASM_VECTOR_LEN;
        var ptr1 = isLikeNone(password) ? 0 : passStringToWasm0(password, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
        var len1 = WASM_VECTOR_LEN;
        wasm.import_ssh_key(retptr, ptr0, len0, ptr1, len1);
        var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
        var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
        var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
        if (r2) {
            throw takeObject(r1);
        }
        return takeObject(r0);
    } finally {
        wasm.__wbindgen_add_to_stack_pointer(16);
    }
}

/**
 * Initialize the SDK. Must be called before using any other API.
 * Only the first invocation has effect; subsequent calls are ignored.
 *
 * - `log_level`: Minimum level for console output. Defaults to `Info`.
 * - `flight_recorder_level`: Minimum level for the flight recorder. Defaults to `Info`.
 * - `flight_recorder_buffer_size`: Ring-buffer capacity for the flight recorder. Defaults to 1000.
 *   Pass `0` to disable the flight recorder entirely.
 * @param {LogLevel | null} [log_level]
 * @param {LogLevel | null} [flight_recorder_level]
 * @param {number | null} [flight_recorder_buffer_size]
 */
function init_sdk(log_level, flight_recorder_level, flight_recorder_buffer_size) {
    wasm.init_sdk(isLikeNone(log_level) ? 5 : log_level, isLikeNone(flight_recorder_level) ? 5 : flight_recorder_level, isLikeNone(flight_recorder_buffer_size) ? 0x100000001 : (flight_recorder_buffer_size) >>> 0);
}

/**
 * Registers a DiscoverHandler so that the client can respond to DiscoverRequests.
 * @param {IpcClient} ipc_client
 * @param {DiscoverResponse} response
 * @returns {Promise<void>}
 */
function ipcRegisterDiscoverHandler(ipc_client, response) {
    _assertClass(ipc_client, IpcClient);
    const ret = wasm.ipcRegisterDiscoverHandler(ipc_client.__wbg_ptr, addHeapObject(response));
    return takeObject(ret);
}

/**
 * Sends a DiscoverRequest to the specified destination and returns the response.
 * @param {IpcClient} ipc_client
 * @param {Endpoint} destination
 * @param {AbortSignal | null} [abort_signal]
 * @returns {Promise<DiscoverResponse>}
 */
function ipcRequestDiscover(ipc_client, destination, abort_signal) {
    _assertClass(ipc_client, IpcClient);
    const ret = wasm.ipcRequestDiscover(ipc_client.__wbg_ptr, addHeapObject(destination), isLikeNone(abort_signal) ? 0 : addHeapObject(abort_signal));
    return takeObject(ret);
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isAccountCryptographyInitializationError(error) {
    try {
        const ret = wasm.isAccountCryptographyInitializationError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isAcquireCookieError(error) {
    try {
        const ret = wasm.isAcquireCookieError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isAlreadyRunningError(error) {
    try {
        const ret = wasm.isAlreadyRunningError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isCallError(error) {
    try {
        const ret = wasm.isCallError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isChannelError(error) {
    try {
        const ret = wasm.isChannelError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isCipherDeleteAttachmentError(error) {
    try {
        const ret = wasm.isCipherDeleteAttachmentError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isCipherError(error) {
    try {
        const ret = wasm.isCipherError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isCipherRiskError(error) {
    try {
        const ret = wasm.isCipherRiskError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isCollectionDecryptError(error) {
    try {
        const ret = wasm.isCollectionDecryptError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isCreateCipherAdminError(error) {
    try {
        const ret = wasm.isCreateCipherAdminError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isCreateCipherError(error) {
    try {
        const ret = wasm.isCreateCipherError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isCreateFolderError(error) {
    try {
        const ret = wasm.isCreateFolderError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isCreateSendError(error) {
    try {
        const ret = wasm.isCreateSendError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isCryptoClientError(error) {
    try {
        const ret = wasm.isCryptoClientError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isCryptoError(error) {
    try {
        const ret = wasm.isCryptoError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isDatabaseError(error) {
    try {
        const ret = wasm.isDatabaseError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isDecryptError(error) {
    try {
        const ret = wasm.isDecryptError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isDecryptFileError(error) {
    try {
        const ret = wasm.isDecryptFileError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isDeleteAttachmentAdminError(error) {
    try {
        const ret = wasm.isDeleteAttachmentAdminError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isDeleteCipherAdminError(error) {
    try {
        const ret = wasm.isDeleteCipherAdminError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isDeleteCipherError(error) {
    try {
        const ret = wasm.isDeleteCipherError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isDeriveKeyConnectorError(error) {
    try {
        const ret = wasm.isDeriveKeyConnectorError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isDeserializeError(error) {
    try {
        const ret = wasm.isDeserializeError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isEditCipherAdminError(error) {
    try {
        const ret = wasm.isEditCipherAdminError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isEditCipherError(error) {
    try {
        const ret = wasm.isEditCipherError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isEditFolderError(error) {
    try {
        const ret = wasm.isEditFolderError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isEditSendError(error) {
    try {
        const ret = wasm.isEditSendError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isEncryptError(error) {
    try {
        const ret = wasm.isEncryptError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isEncryptFileError(error) {
    try {
        const ret = wasm.isEncryptFileError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isEncryptionSettingsError(error) {
    try {
        const ret = wasm.isEncryptionSettingsError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isEnrollAdminPasswordResetError(error) {
    try {
        const ret = wasm.isEnrollAdminPasswordResetError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isExportError(error) {
    try {
        const ret = wasm.isExportError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isGetCipherError(error) {
    try {
        const ret = wasm.isGetCipherError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isGetFolderError(error) {
    try {
        const ret = wasm.isGetFolderError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isGetOrganizationCiphersAdminError(error) {
    try {
        const ret = wasm.isGetOrganizationCiphersAdminError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isGetSendError(error) {
    try {
        const ret = wasm.isGetSendError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isKeyGenerationError(error) {
    try {
        const ret = wasm.isKeyGenerationError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isMakeKeysError(error) {
    try {
        const ret = wasm.isMakeKeysError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isMasterPasswordError(error) {
    try {
        const ret = wasm.isMasterPasswordError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isMigrateToKeyConnectorError(error) {
    try {
        const ret = wasm.isMigrateToKeyConnectorError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isPasswordError(error) {
    try {
        const ret = wasm.isPasswordError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isPasswordLoginError(error) {
    try {
        const ret = wasm.isPasswordLoginError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isPasswordPreloginError(error) {
    try {
        const ret = wasm.isPasswordPreloginError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isReceiveError(error) {
    try {
        const ret = wasm.isReceiveError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isRegistrationError(error) {
    try {
        const ret = wasm.isRegistrationError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isRequestError(error) {
    try {
        const ret = wasm.isRequestError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isRestoreCipherAdminError(error) {
    try {
        const ret = wasm.isRestoreCipherAdminError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isRestoreCipherError(error) {
    try {
        const ret = wasm.isRestoreCipherError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isRotateCryptographyStateError(error) {
    try {
        const ret = wasm.isRotateCryptographyStateError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isRotateUserKeysError(error) {
    try {
        const ret = wasm.isRotateUserKeysError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isServerCommunicationConfigRepositoryError(error) {
    try {
        const ret = wasm.isServerCommunicationConfigRepositoryError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isSshKeyExportError(error) {
    try {
        const ret = wasm.isSshKeyExportError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isSshKeyImportError(error) {
    try {
        const ret = wasm.isSshKeyImportError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isStateRegistryError(error) {
    try {
        const ret = wasm.isStateRegistryError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isStatefulCryptoError(error) {
    try {
        const ret = wasm.isStatefulCryptoError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isSubscribeError(error) {
    try {
        const ret = wasm.isSubscribeError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isSyncError(error) {
    try {
        const ret = wasm.isSyncError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isTestError(error) {
    try {
        const ret = wasm.isTestError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isTotpError(error) {
    try {
        const ret = wasm.isTotpError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isTypedReceiveError(error) {
    try {
        const ret = wasm.isTypedReceiveError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}

/**
 * @param {any} error
 * @returns {boolean}
 */
function isUsernameError(error) {
    try {
        const ret = wasm.isUsernameError(addBorrowedObject(error));
        return ret !== 0;
    } finally {
        heap[stack_pointer++] = undefined;
    }
}
function __wbg_Error_83742b46f01ce22d(arg0, arg1) {
    const ret = Error(getStringFromWasm0(arg0, arg1));
    return addHeapObject(ret);
}
function __wbg_Number_a5a435bd7bbec835(arg0) {
    const ret = Number(getObject(arg0));
    return ret;
}
function __wbg_String_8564e559799eccda(arg0, arg1) {
    const ret = String(getObject(arg1));
    const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
    const len1 = WASM_VECTOR_LEN;
    getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
    getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
}
function __wbg___wbindgen_bigint_get_as_i64_447a76b5c6ef7bda(arg0, arg1) {
    const v = getObject(arg1);
    const ret = typeof(v) === 'bigint' ? v : undefined;
    getDataViewMemory0().setBigInt64(arg0 + 8 * 1, isLikeNone(ret) ? BigInt(0) : ret, true);
    getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true);
}
function __wbg___wbindgen_boolean_get_c0f3f60bac5a78d1(arg0) {
    const v = getObject(arg0);
    const ret = typeof(v) === 'boolean' ? v : undefined;
    return isLikeNone(ret) ? 0xFFFFFF : ret ? 1 : 0;
}
function __wbg___wbindgen_debug_string_5398f5bb970e0daa(arg0, arg1) {
    const ret = debugString(getObject(arg1));
    const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
    const len1 = WASM_VECTOR_LEN;
    getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
    getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
}
function __wbg___wbindgen_in_41dbb8413020e076(arg0, arg1) {
    const ret = getObject(arg0) in getObject(arg1);
    return ret;
}
function __wbg___wbindgen_is_bigint_e2141d4f045b7eda(arg0) {
    const ret = typeof(getObject(arg0)) === 'bigint';
    return ret;
}
function __wbg___wbindgen_is_function_3c846841762788c1(arg0) {
    const ret = typeof(getObject(arg0)) === 'function';
    return ret;
}
function __wbg___wbindgen_is_null_0b605fc6b167c56f(arg0) {
    const ret = getObject(arg0) === null;
    return ret;
}
function __wbg___wbindgen_is_object_781bc9f159099513(arg0) {
    const val = getObject(arg0);
    const ret = typeof(val) === 'object' && val !== null;
    return ret;
}
function __wbg___wbindgen_is_string_7ef6b97b02428fae(arg0) {
    const ret = typeof(getObject(arg0)) === 'string';
    return ret;
}
function __wbg___wbindgen_is_undefined_52709e72fb9f179c(arg0) {
    const ret = getObject(arg0) === undefined;
    return ret;
}
function __wbg___wbindgen_jsval_eq_ee31bfad3e536463(arg0, arg1) {
    const ret = getObject(arg0) === getObject(arg1);
    return ret;
}
function __wbg___wbindgen_jsval_loose_eq_5bcc3bed3c69e72b(arg0, arg1) {
    const ret = getObject(arg0) == getObject(arg1);
    return ret;
}
function __wbg___wbindgen_number_get_34bb9d9dcfa21373(arg0, arg1) {
    const obj = getObject(arg1);
    const ret = typeof(obj) === 'number' ? obj : undefined;
    getDataViewMemory0().setFloat64(arg0 + 8 * 1, isLikeNone(ret) ? 0 : ret, true);
    getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true);
}
function __wbg___wbindgen_string_get_395e606bd0ee4427(arg0, arg1) {
    const obj = getObject(arg1);
    const ret = typeof(obj) === 'string' ? obj : undefined;
    var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
    var len1 = WASM_VECTOR_LEN;
    getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
    getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
}
function __wbg___wbindgen_throw_6ddd609b62940d55(arg0, arg1) {
    throw new Error(getStringFromWasm0(arg0, arg1));
}
function __wbg__wbg_cb_unref_6b5b6b8576d35cb1(arg0) {
    getObject(arg0)._wbg_cb_unref();
}
function __wbg_abort_5ef96933660780b7(arg0) {
    getObject(arg0).abort();
}
function __wbg_abort_60dcb252ae0031fc() { return handleError(function (arg0) {
    getObject(arg0).abort();
}, arguments); }
function __wbg_abort_6479c2d794ebf2ee(arg0, arg1) {
    getObject(arg0).abort(getObject(arg1));
}
function __wbg_acquireCookies_6c408397b3a34df5() { return handleError(function (arg0, arg1, arg2) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg1;
        deferred0_1 = arg2;
        const ret = getObject(arg0).acquireCookies(getStringFromWasm0(arg1, arg2));
        return addHeapObject(ret);
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}, arguments); }
function __wbg_addEventListener_14aecf4b28f9db02(arg0, arg1, arg2, arg3) {
    getObject(arg0).addEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3));
}
function __wbg_append_48b3d4fc4c97ab8d() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
    getObject(arg0).append(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
}, arguments); }
function __wbg_append_608dfb635ee8998f() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
    getObject(arg0).append(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
}, arguments); }
function __wbg_append_83e47d4b428d97aa() { return handleError(function (arg0, arg1, arg2, arg3) {
    getObject(arg0).append(getStringFromWasm0(arg1, arg2), getObject(arg3));
}, arguments); }
function __wbg_append_bbf73d7e78ce268c() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) {
    getObject(arg0).append(getStringFromWasm0(arg1, arg2), getObject(arg3), getStringFromWasm0(arg4, arg5));
}, arguments); }
function __wbg_arrayBuffer_eb8e9ca620af2a19() { return handleError(function (arg0) {
    const ret = getObject(arg0).arrayBuffer();
    return addHeapObject(ret);
}, arguments); }
function __wbg_call_2d781c1f4d5c0ef8() { return handleError(function (arg0, arg1, arg2) {
    const ret = getObject(arg0).call(getObject(arg1), getObject(arg2));
    return addHeapObject(ret);
}, arguments); }
function __wbg_call_e133b57c9155d22c() { return handleError(function (arg0, arg1) {
    const ret = getObject(arg0).call(getObject(arg1));
    return addHeapObject(ret);
}, arguments); }
function __wbg_cipher_3d45684f136684e7(arg0) {
    const ret = getObject(arg0).cipher;
    return isLikeNone(ret) ? 0 : addHeapObject(ret);
}
function __wbg_clearTimeout_6b8d9a38b9263d65(arg0) {
    const ret = clearTimeout(takeObject(arg0));
    return addHeapObject(ret);
}
function __wbg_clear_1885f7bf35006b0c() { return handleError(function (arg0) {
    const ret = getObject(arg0).clear();
    return addHeapObject(ret);
}, arguments); }
function __wbg_collectionviewnodeitem_new(arg0) {
    const ret = CollectionViewNodeItem.__wrap(arg0);
    return addHeapObject(ret);
}
function __wbg_create_e9e35ffcb49d7084(arg0) {
    const ret = Object.create(getObject(arg0));
    return addHeapObject(ret);
}
function __wbg_debug_271c16e6de0bc226(arg0, arg1, arg2, arg3) {
    console.debug(getObject(arg0), getObject(arg1), getObject(arg2), getObject(arg3));
}
function __wbg_debug_4b9b1a2d5972be57(arg0) {
    console.debug(getObject(arg0));
}
function __wbg_delete_40db93c05c546fb9() { return handleError(function (arg0, arg1) {
    const ret = getObject(arg0).delete(getObject(arg1));
    return addHeapObject(ret);
}, arguments); }
function __wbg_done_08ce71ee07e3bd17(arg0) {
    const ret = getObject(arg0).done;
    return ret;
}
function __wbg_entries_e8a20ff8c9757101(arg0) {
    const ret = Object.entries(getObject(arg0));
    return addHeapObject(ret);
}
function __wbg_ephemeral_pin_envelope_state_a57f8d9c123d28c6(arg0) {
    const ret = getObject(arg0).ephemeral_pin_envelope_state;
    return isLikeNone(ret) ? 0 : addHeapObject(ret);
}
function __wbg_error_1eece6b0039034ce(arg0, arg1, arg2, arg3) {
    console.error(getObject(arg0), getObject(arg1), getObject(arg2), getObject(arg3));
}
function __wbg_error_74898554122344a8() { return handleError(function (arg0) {
    const ret = getObject(arg0).error;
    return isLikeNone(ret) ? 0 : addHeapObject(ret);
}, arguments); }
function __wbg_error_8d9a8e04cd1d3588(arg0) {
    console.error(getObject(arg0));
}
function __wbg_error_a6fa202b58aa1cd3(arg0, arg1) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg0;
        deferred0_1 = arg1;
        console.error(getStringFromWasm0(arg0, arg1));
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}
function __wbg_fetch_5550a88cf343aaa9(arg0, arg1) {
    const ret = getObject(arg0).fetch(getObject(arg1));
    return addHeapObject(ret);
}
function __wbg_fetch_9dad4fe911207b37(arg0) {
    const ret = fetch(getObject(arg0));
    return addHeapObject(ret);
}
function __wbg_folder_0b01534304da4704(arg0) {
    const ret = getObject(arg0).folder;
    return isLikeNone(ret) ? 0 : addHeapObject(ret);
}
function __wbg_getAll_690f659b57ae2d51() { return handleError(function (arg0) {
    const ret = getObject(arg0).getAll();
    return addHeapObject(ret);
}, arguments); }
function __wbg_getFullYear_f6d84c054eee1543(arg0) {
    const ret = getObject(arg0).getFullYear();
    return ret;
}
function __wbg_getRandomValues_76dfc69825c9c552() { return handleError(function (arg0, arg1) {
    globalThis.crypto.getRandomValues(getArrayU8FromWasm0(arg0, arg1));
}, arguments); }
function __wbg_getRandomValues_ef12552bf5acd2fe() { return handleError(function (arg0, arg1) {
    globalThis.crypto.getRandomValues(getArrayU8FromWasm0(arg0, arg1));
}, arguments); }
function __wbg_getTime_1dad7b5386ddd2d9(arg0) {
    const ret = getObject(arg0).getTime();
    return ret;
}
function __wbg_get_1a199cb285f5075b() { return handleError(function (arg0, arg1, arg2) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg1;
        deferred0_1 = arg2;
        const ret = getObject(arg0).get(getStringFromWasm0(arg1, arg2));
        return addHeapObject(ret);
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}, arguments); }
function __wbg_get_2ccd8acbf5c86922() { return handleError(function (arg0, arg1, arg2) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg1;
        deferred0_1 = arg2;
        const ret = getObject(arg0).get(getStringFromWasm0(arg1, arg2));
        return addHeapObject(ret);
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}, arguments); }
function __wbg_get_326e41e095fb2575() { return handleError(function (arg0, arg1) {
    const ret = Reflect.get(getObject(arg0), getObject(arg1));
    return addHeapObject(ret);
}, arguments); }
function __wbg_get_3ef1eba1850ade27() { return handleError(function (arg0, arg1) {
    const ret = Reflect.get(getObject(arg0), getObject(arg1));
    return addHeapObject(ret);
}, arguments); }
function __wbg_get_6ac8c8119f577720() { return handleError(function (arg0, arg1) {
    const ret = getObject(arg0).get(getObject(arg1));
    return addHeapObject(ret);
}, arguments); }
function __wbg_get_9558fffcf2da2e5d() { return handleError(function (arg0, arg1, arg2) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg1;
        deferred0_1 = arg2;
        const ret = getObject(arg0).get(getStringFromWasm0(arg1, arg2));
        return addHeapObject(ret);
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}, arguments); }
function __wbg_get_a8ee5c45dabc1b3b(arg0, arg1) {
    const ret = getObject(arg0)[arg1 >>> 0];
    return addHeapObject(ret);
}
function __wbg_get_ab6398926dce696f() { return handleError(function (arg0, arg1, arg2) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg1;
        deferred0_1 = arg2;
        const ret = getObject(arg0).get(getStringFromWasm0(arg1, arg2));
        return addHeapObject(ret);
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}, arguments); }
function __wbg_get_access_token_b777a991688c2b49(arg0) {
    const ret = getObject(arg0).get_access_token();
    return addHeapObject(ret);
}
function __wbg_get_bc1924700555f403() { return handleError(function (arg0, arg1, arg2) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg1;
        deferred0_1 = arg2;
        const ret = getObject(arg0).get(getStringFromWasm0(arg1, arg2));
        return addHeapObject(ret);
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}, arguments); }
function __wbg_get_ec32bde1b0c823cc() { return handleError(function (arg0, arg1, arg2) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg1;
        deferred0_1 = arg2;
        const ret = getObject(arg0).get(getStringFromWasm0(arg1, arg2));
        return addHeapObject(ret);
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}, arguments); }
function __wbg_get_f8121c4a2fc8fb5b() { return handleError(function (arg0, arg1, arg2) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg1;
        deferred0_1 = arg2;
        const ret = getObject(arg0).get(getStringFromWasm0(arg1, arg2));
        return addHeapObject(ret);
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}, arguments); }
function __wbg_get_unchecked_329cfe50afab7352(arg0, arg1) {
    const ret = getObject(arg0)[arg1 >>> 0];
    return addHeapObject(ret);
}
function __wbg_get_with_ref_key_6412cf3094599694(arg0, arg1) {
    const ret = getObject(arg0)[getObject(arg1)];
    return addHeapObject(ret);
}
function __wbg_has_926ef2ff40b308cf() { return handleError(function (arg0, arg1) {
    const ret = Reflect.has(getObject(arg0), getObject(arg1));
    return ret;
}, arguments); }
function __wbg_headers_eb2234545f9ff993(arg0) {
    const ret = getObject(arg0).headers;
    return addHeapObject(ret);
}
function __wbg_incomingmessage_new(arg0) {
    const ret = IncomingMessage.__wrap(arg0);
    return addHeapObject(ret);
}
function __wbg_info_0194681687b5ab04(arg0, arg1, arg2, arg3) {
    console.info(getObject(arg0), getObject(arg1), getObject(arg2), getObject(arg3));
}
function __wbg_info_7d4e223bb1a7e671(arg0) {
    console.info(getObject(arg0));
}
function __wbg_instanceof_ArrayBuffer_101e2bf31071a9f6(arg0) {
    let result;
    try {
        result = getObject(arg0) instanceof ArrayBuffer;
    } catch (_) {
        result = false;
    }
    const ret = result;
    return ret;
}
function __wbg_instanceof_DomException_2bdcf7791a2d7d09(arg0) {
    let result;
    try {
        result = getObject(arg0) instanceof DOMException;
    } catch (_) {
        result = false;
    }
    const ret = result;
    return ret;
}
function __wbg_instanceof_IdbRequest_6a0e24572d4f1d46(arg0) {
    let result;
    try {
        result = getObject(arg0) instanceof IDBRequest;
    } catch (_) {
        result = false;
    }
    const ret = result;
    return ret;
}
function __wbg_instanceof_Map_f194b366846aca0c(arg0) {
    let result;
    try {
        result = getObject(arg0) instanceof Map;
    } catch (_) {
        result = false;
    }
    const ret = result;
    return ret;
}
function __wbg_instanceof_Response_9b4d9fd451e051b1(arg0) {
    let result;
    try {
        result = getObject(arg0) instanceof Response;
    } catch (_) {
        result = false;
    }
    const ret = result;
    return ret;
}
function __wbg_instanceof_Uint8Array_740438561a5b956d(arg0) {
    let result;
    try {
        result = getObject(arg0) instanceof Uint8Array;
    } catch (_) {
        result = false;
    }
    const ret = result;
    return ret;
}
function __wbg_ipcclientsubscription_new(arg0) {
    const ret = IpcClientSubscription.__wrap(arg0);
    return addHeapObject(ret);
}
function __wbg_isArray_33b91feb269ff46e(arg0) {
    const ret = Array.isArray(getObject(arg0));
    return ret;
}
function __wbg_isSafeInteger_ecd6a7f9c3e053cd(arg0) {
    const ret = Number.isSafeInteger(getObject(arg0));
    return ret;
}
function __wbg_iterator_d8f549ec8fb061b1() {
    const ret = Symbol.iterator;
    return addHeapObject(ret);
}
function __wbg_length_b3416cf66a5452c8(arg0) {
    const ret = getObject(arg0).length;
    return ret;
}
function __wbg_length_ea16607d7b61445b(arg0) {
    const ret = getObject(arg0).length;
    return ret;
}
function __wbg_list_0fdaff8918a551c3() { return handleError(function (arg0) {
    const ret = getObject(arg0).list();
    return addHeapObject(ret);
}, arguments); }
function __wbg_list_2f90f406548f9445() { return handleError(function (arg0) {
    const ret = getObject(arg0).list();
    return addHeapObject(ret);
}, arguments); }
function __wbg_list_7a28414a08b60036() { return handleError(function (arg0) {
    const ret = getObject(arg0).list();
    return addHeapObject(ret);
}, arguments); }
function __wbg_list_92ac9ca899e49952() { return handleError(function (arg0) {
    const ret = getObject(arg0).list();
    return addHeapObject(ret);
}, arguments); }
function __wbg_list_c37805a6bea723d5() { return handleError(function (arg0) {
    const ret = getObject(arg0).list();
    return addHeapObject(ret);
}, arguments); }
function __wbg_list_e9a4d8a1346dd88b() { return handleError(function (arg0) {
    const ret = getObject(arg0).list();
    return addHeapObject(ret);
}, arguments); }
function __wbg_local_user_data_key_state_a42fa6c432ab2a9e(arg0) {
    const ret = getObject(arg0).local_user_data_key_state;
    return isLikeNone(ret) ? 0 : addHeapObject(ret);
}
function __wbg_mark_310e9a031ccc84ff() { return handleError(function (arg0, arg1, arg2) {
    getObject(arg0).mark(getStringFromWasm0(arg1, arg2));
}, arguments); }
function __wbg_mark_742962d66a858cc5() { return handleError(function (arg0, arg1, arg2, arg3) {
    getObject(arg0).mark(getStringFromWasm0(arg1, arg2), getObject(arg3));
}, arguments); }
function __wbg_measure_54743279e77e77bb() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5, arg6) {
    getObject(arg0).measure(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4), getStringFromWasm0(arg5, arg6));
}, arguments); }
function __wbg_measure_cd1f7667d5f5517d() { return handleError(function (arg0, arg1, arg2, arg3) {
    getObject(arg0).measure(getStringFromWasm0(arg1, arg2), getObject(arg3));
}, arguments); }
function __wbg_name_7a3bbd030d0afa16(arg0, arg1) {
    const ret = getObject(arg1).name;
    const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
    const len1 = WASM_VECTOR_LEN;
    getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
    getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
}
function __wbg_new_0837727332ac86ba() { return handleError(function () {
    const ret = new Headers();
    return addHeapObject(ret);
}, arguments); }
function __wbg_new_0_1dcafdf5e786e876() {
    const ret = new Date();
    return addHeapObject(ret);
}
function __wbg_new_227d7c05414eb861() {
    const ret = new Error();
    return addHeapObject(ret);
}
function __wbg_new_2d996564533475e2(arg0, arg1) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg0;
        deferred0_1 = arg1;
        const ret = new Error(getStringFromWasm0(arg0, arg1));
        return addHeapObject(ret);
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}
function __wbg_new_49d5571bd3f0c4d4() {
    const ret = new Map();
    return addHeapObject(ret);
}
function __wbg_new_5cfc6a14488ab25a() { return handleError(function () {
    const ret = new FormData();
    return addHeapObject(ret);
}, arguments); }
function __wbg_new_5f486cdf45a04d78(arg0) {
    const ret = new Uint8Array(getObject(arg0));
    return addHeapObject(ret);
}
function __wbg_new_a70fbab9066b301f() {
    const ret = new Array();
    return addHeapObject(ret);
}
function __wbg_new_ab79df5bd7c26067() {
    const ret = new Object();
    return addHeapObject(ret);
}
function __wbg_new_c518c60af666645b() { return handleError(function () {
    const ret = new AbortController();
    return addHeapObject(ret);
}, arguments); }
function __wbg_new_d15cb560a6a0e5f0(arg0, arg1) {
    const ret = new Error(getStringFromWasm0(arg0, arg1));
    return addHeapObject(ret);
}
function __wbg_new_from_slice_22da9388ac046e50(arg0, arg1) {
    const ret = new Uint8Array(getArrayU8FromWasm0(arg0, arg1));
    return addHeapObject(ret);
}
function __wbg_new_typed_aaaeaf29cf802876(arg0, arg1) {
    try {
        var state0 = {a: arg0, b: arg1};
        var cb0 = (arg0, arg1) => {
            const a = state0.a;
            state0.a = 0;
            try {
                return wasm_bindgen_296f817121844f10___convert__closures_____invoke___js_sys_b1bce590f5d90a2___Function_fn_wasm_bindgen_296f817121844f10___JsValue_____wasm_bindgen_296f817121844f10___sys__Undefined___js_sys_b1bce590f5d90a2___Function_fn_wasm_bindgen_296f817121844f10___JsValue_____wasm_bindgen_296f817121844f10___sys__Undefined_______true_(a, state0.b, arg0, arg1);
            } finally {
                state0.a = a;
            }
        };
        const ret = new Promise(cb0);
        return addHeapObject(ret);
    } finally {
        state0.a = state0.b = 0;
    }
}
function __wbg_new_with_length_3259a525196bd8cc(arg0) {
    const ret = new Array(arg0 >>> 0);
    return addHeapObject(ret);
}
function __wbg_new_with_str_and_init_b4b54d1a819bc724() { return handleError(function (arg0, arg1, arg2) {
    const ret = new Request(getStringFromWasm0(arg0, arg1), getObject(arg2));
    return addHeapObject(ret);
}, arguments); }
function __wbg_new_with_u8_array_sequence_and_options_de38f663e19ad899() { return handleError(function (arg0, arg1) {
    const ret = new Blob(getObject(arg0), getObject(arg1));
    return addHeapObject(ret);
}, arguments); }
function __wbg_next_11b99ee6237339e3() { return handleError(function (arg0) {
    const ret = getObject(arg0).next();
    return addHeapObject(ret);
}, arguments); }
function __wbg_next_e01a967809d1aa68(arg0) {
    const ret = getObject(arg0).next;
    return addHeapObject(ret);
}
function __wbg_now_c6d7a7d35f74f6f1(arg0) {
    const ret = getObject(arg0).now();
    return ret;
}
function __wbg_objectStore_f314ab152a5c7bd0() { return handleError(function (arg0, arg1, arg2) {
    const ret = getObject(arg0).objectStore(getStringFromWasm0(arg1, arg2));
    return addHeapObject(ret);
}, arguments); }
function __wbg_organization_shared_key_eff6fc3c86be0319(arg0) {
    const ret = getObject(arg0).organization_shared_key;
    return isLikeNone(ret) ? 0 : addHeapObject(ret);
}
function __wbg_parse_e9eddd2a82c706eb() { return handleError(function (arg0, arg1) {
    const ret = JSON.parse(getStringFromWasm0(arg0, arg1));
    return addHeapObject(ret);
}, arguments); }
function __wbg_performance_757310249566272b() {
    const ret = globalThis.performance;
    return addHeapObject(ret);
}
function __wbg_preventDefault_25a229bfe5c510f8(arg0) {
    getObject(arg0).preventDefault();
}
function __wbg_prototypesetcall_d62e5099504357e6(arg0, arg1, arg2) {
    Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), getObject(arg2));
}
function __wbg_push_e87b0e732085a946(arg0, arg1) {
    const ret = getObject(arg0).push(getObject(arg1));
    return ret;
}
function __wbg_put_f1673d719f93ce22() { return handleError(function (arg0, arg1, arg2) {
    const ret = getObject(arg0).put(getObject(arg1), getObject(arg2));
    return addHeapObject(ret);
}, arguments); }
function __wbg_queueMicrotask_0c399741342fb10f(arg0) {
    const ret = getObject(arg0).queueMicrotask;
    return addHeapObject(ret);
}
function __wbg_queueMicrotask_a082d78ce798393e(arg0) {
    queueMicrotask(getObject(arg0));
}
function __wbg_removeAll_021cbeb363328530() { return handleError(function (arg0) {
    const ret = getObject(arg0).removeAll();
    return addHeapObject(ret);
}, arguments); }
function __wbg_removeAll_30b3939f3f5c8bdf() { return handleError(function (arg0) {
    const ret = getObject(arg0).removeAll();
    return addHeapObject(ret);
}, arguments); }
function __wbg_removeAll_83d9b879edf3edf5() { return handleError(function (arg0) {
    const ret = getObject(arg0).removeAll();
    return addHeapObject(ret);
}, arguments); }
function __wbg_removeAll_d2bf38f9bc9aea1f() { return handleError(function (arg0) {
    const ret = getObject(arg0).removeAll();
    return addHeapObject(ret);
}, arguments); }
function __wbg_removeAll_e37dca02c04bad64() { return handleError(function (arg0) {
    const ret = getObject(arg0).removeAll();
    return addHeapObject(ret);
}, arguments); }
function __wbg_removeAll_f058d82b1aa15ca5() { return handleError(function (arg0) {
    const ret = getObject(arg0).removeAll();
    return addHeapObject(ret);
}, arguments); }
function __wbg_removeBulk_1b4de37c14766bfc() { return handleError(function (arg0, arg1) {
    const ret = getObject(arg0).removeBulk(takeObject(arg1));
    return addHeapObject(ret);
}, arguments); }
function __wbg_removeBulk_452b7a89d11d0694() { return handleError(function (arg0, arg1) {
    const ret = getObject(arg0).removeBulk(takeObject(arg1));
    return addHeapObject(ret);
}, arguments); }
function __wbg_removeBulk_7898e06fc6e85501() { return handleError(function (arg0, arg1) {
    const ret = getObject(arg0).removeBulk(takeObject(arg1));
    return addHeapObject(ret);
}, arguments); }
function __wbg_removeBulk_ac338f90b239797d() { return handleError(function (arg0, arg1) {
    const ret = getObject(arg0).removeBulk(takeObject(arg1));
    return addHeapObject(ret);
}, arguments); }
function __wbg_removeBulk_e18ea7127397fa26() { return handleError(function (arg0, arg1) {
    const ret = getObject(arg0).removeBulk(takeObject(arg1));
    return addHeapObject(ret);
}, arguments); }
function __wbg_removeBulk_e55dcd29d10ae184() { return handleError(function (arg0, arg1) {
    const ret = getObject(arg0).removeBulk(takeObject(arg1));
    return addHeapObject(ret);
}, arguments); }
function __wbg_remove_11c0c0ad23369948() { return handleError(function (arg0, arg1, arg2) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg1;
        deferred0_1 = arg2;
        const ret = getObject(arg0).remove(getStringFromWasm0(arg1, arg2));
        return addHeapObject(ret);
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}, arguments); }
function __wbg_remove_2a05e82532412f41() { return handleError(function (arg0, arg1, arg2) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg1;
        deferred0_1 = arg2;
        const ret = getObject(arg0).remove(getStringFromWasm0(arg1, arg2));
        return addHeapObject(ret);
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}, arguments); }
function __wbg_remove_36a0891eeaffb08e() { return handleError(function (arg0, arg1, arg2) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg1;
        deferred0_1 = arg2;
        const ret = getObject(arg0).remove(getStringFromWasm0(arg1, arg2));
        return addHeapObject(ret);
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}, arguments); }
function __wbg_remove_433cff70ed894243() { return handleError(function (arg0, arg1, arg2) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg1;
        deferred0_1 = arg2;
        const ret = getObject(arg0).remove(getStringFromWasm0(arg1, arg2));
        return addHeapObject(ret);
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}, arguments); }
function __wbg_remove_6a2ee8e510094e40() { return handleError(function (arg0, arg1, arg2) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg1;
        deferred0_1 = arg2;
        const ret = getObject(arg0).remove(getStringFromWasm0(arg1, arg2));
        return addHeapObject(ret);
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}, arguments); }
function __wbg_remove_6dd84ec06dcd438d() { return handleError(function (arg0, arg1, arg2) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg1;
        deferred0_1 = arg2;
        const ret = getObject(arg0).remove(getStringFromWasm0(arg1, arg2));
        return addHeapObject(ret);
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}, arguments); }
function __wbg_resolve_ae8d83246e5bcc12(arg0) {
    const ret = Promise.resolve(getObject(arg0));
    return addHeapObject(ret);
}
function __wbg_result_c5baa2d3d690a01a() { return handleError(function (arg0) {
    const ret = getObject(arg0).result;
    return addHeapObject(ret);
}, arguments); }
function __wbg_save_68ac7f7c3c522f0f() { return handleError(function (arg0, arg1, arg2, arg3) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg1;
        deferred0_1 = arg2;
        const ret = getObject(arg0).save(getStringFromWasm0(arg1, arg2), takeObject(arg3));
        return addHeapObject(ret);
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}, arguments); }
function __wbg_send_bc57e3d44b1ae6d7() { return handleError(function (arg0, arg1) {
    const ret = getObject(arg0).send(OutgoingMessage.__wrap(arg1));
    return addHeapObject(ret);
}, arguments); }
function __wbg_setBulk_11b4b57960e030a6() { return handleError(function (arg0, arg1) {
    const ret = getObject(arg0).setBulk(takeObject(arg1));
    return addHeapObject(ret);
}, arguments); }
function __wbg_setBulk_19a0b37f4955b796() { return handleError(function (arg0, arg1) {
    const ret = getObject(arg0).setBulk(takeObject(arg1));
    return addHeapObject(ret);
}, arguments); }
function __wbg_setBulk_24eb76b34ac7d59a() { return handleError(function (arg0, arg1) {
    const ret = getObject(arg0).setBulk(takeObject(arg1));
    return addHeapObject(ret);
}, arguments); }
function __wbg_setBulk_65ae23b49b7055f4() { return handleError(function (arg0, arg1) {
    const ret = getObject(arg0).setBulk(takeObject(arg1));
    return addHeapObject(ret);
}, arguments); }
function __wbg_setBulk_e7f56f73e97d6782() { return handleError(function (arg0, arg1) {
    const ret = getObject(arg0).setBulk(takeObject(arg1));
    return addHeapObject(ret);
}, arguments); }
function __wbg_setBulk_eb51976bf9f6732d() { return handleError(function (arg0, arg1) {
    const ret = getObject(arg0).setBulk(takeObject(arg1));
    return addHeapObject(ret);
}, arguments); }
function __wbg_setTimeout_f757f00851f76c42(arg0, arg1) {
    const ret = setTimeout(getObject(arg0), arg1);
    return addHeapObject(ret);
}
function __wbg_set_107d6f53da51edcf() { return handleError(function (arg0, arg1, arg2, arg3) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg1;
        deferred0_1 = arg2;
        const ret = getObject(arg0).set(getStringFromWasm0(arg1, arg2), takeObject(arg3));
        return addHeapObject(ret);
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}, arguments); }
function __wbg_set_11072e94887ebb20() { return handleError(function (arg0, arg1, arg2, arg3) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg1;
        deferred0_1 = arg2;
        const ret = getObject(arg0).set(getStringFromWasm0(arg1, arg2), takeObject(arg3));
        return addHeapObject(ret);
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}, arguments); }
function __wbg_set_282384002438957f(arg0, arg1, arg2) {
    getObject(arg0)[arg1 >>> 0] = takeObject(arg2);
}
function __wbg_set_48a8c36e440ef4d7() { return handleError(function (arg0, arg1, arg2, arg3) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg1;
        deferred0_1 = arg2;
        const ret = getObject(arg0).set(getStringFromWasm0(arg1, arg2), takeObject(arg3));
        return addHeapObject(ret);
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}, arguments); }
function __wbg_set_6be42768c690e380(arg0, arg1, arg2) {
    getObject(arg0)[takeObject(arg1)] = takeObject(arg2);
}
function __wbg_set_7eaa4f96924fd6b3() { return handleError(function (arg0, arg1, arg2) {
    const ret = Reflect.set(getObject(arg0), getObject(arg1), getObject(arg2));
    return ret;
}, arguments); }
function __wbg_set_9079c80d0e4cae97() { return handleError(function (arg0, arg1, arg2, arg3) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg1;
        deferred0_1 = arg2;
        const ret = getObject(arg0).set(getStringFromWasm0(arg1, arg2), takeObject(arg3));
        return addHeapObject(ret);
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}, arguments); }
function __wbg_set_bf7251625df30a02(arg0, arg1, arg2) {
    const ret = getObject(arg0).set(getObject(arg1), getObject(arg2));
    return addHeapObject(ret);
}
function __wbg_set_body_a3d856b097dfda04(arg0, arg1) {
    getObject(arg0).body = getObject(arg1);
}
function __wbg_set_cache_ec7e430c6056ebda(arg0, arg1) {
    getObject(arg0).cache = __wbindgen_enum_RequestCache[arg1];
}
function __wbg_set_credentials_ed63183445882c65(arg0, arg1) {
    getObject(arg0).credentials = __wbindgen_enum_RequestCredentials[arg1];
}
function __wbg_set_d13ca84b8469dec0() { return handleError(function (arg0, arg1, arg2, arg3) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg1;
        deferred0_1 = arg2;
        const ret = getObject(arg0).set(getStringFromWasm0(arg1, arg2), takeObject(arg3));
        return addHeapObject(ret);
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}, arguments); }
function __wbg_set_f35d433431c47d2f() { return handleError(function (arg0, arg1, arg2, arg3) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg1;
        deferred0_1 = arg2;
        const ret = getObject(arg0).set(getStringFromWasm0(arg1, arg2), takeObject(arg3));
        return addHeapObject(ret);
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}, arguments); }
function __wbg_set_headers_3c8fecc693b75327(arg0, arg1) {
    getObject(arg0).headers = getObject(arg1);
}
function __wbg_set_method_8c015e8bcafd7be1(arg0, arg1, arg2) {
    getObject(arg0).method = getStringFromWasm0(arg1, arg2);
}
function __wbg_set_mode_5a87f2c809cf37c2(arg0, arg1) {
    getObject(arg0).mode = __wbindgen_enum_RequestMode[arg1];
}
function __wbg_set_name_1a2f99370b3248bd(arg0, arg1, arg2) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg1;
        deferred0_1 = arg2;
        getObject(arg0).name = getStringFromWasm0(arg1, arg2);
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}
function __wbg_set_onerror_8a268cb237177bba(arg0, arg1) {
    getObject(arg0).onerror = getObject(arg1);
}
function __wbg_set_onsuccess_fca94ded107b64af(arg0, arg1) {
    getObject(arg0).onsuccess = getObject(arg1);
}
function __wbg_set_signal_0cebecb698f25d21(arg0, arg1) {
    getObject(arg0).signal = getObject(arg1);
}
function __wbg_set_type_33e79f1b45a78c37(arg0, arg1, arg2) {
    getObject(arg0).type = getStringFromWasm0(arg1, arg2);
}
function __wbg_set_variant_8b1ee86f2f7d9515(arg0, arg1, arg2) {
    let deferred0_0;
    let deferred0_1;
    try {
        deferred0_0 = arg1;
        deferred0_1 = arg2;
        getObject(arg0).variant = getStringFromWasm0(arg1, arg2);
    } finally {
        wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
    }
}
function __wbg_signal_166e1da31adcac18(arg0) {
    const ret = getObject(arg0).signal;
    return addHeapObject(ret);
}
function __wbg_stack_3b0d974bbf31e44f(arg0, arg1) {
    const ret = getObject(arg1).stack;
    const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
    const len1 = WASM_VECTOR_LEN;
    getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
    getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
}
function __wbg_static_accessor_GLOBAL_8adb955bd33fac2f() {
    const ret = typeof global === 'undefined' ? null : global;
    return isLikeNone(ret) ? 0 : addHeapObject(ret);
}
function __wbg_static_accessor_GLOBAL_THIS_ad356e0db91c7913() {
    const ret = typeof globalThis === 'undefined' ? null : globalThis;
    return isLikeNone(ret) ? 0 : addHeapObject(ret);
}
function __wbg_static_accessor_SELF_f207c857566db248() {
    const ret = typeof self === 'undefined' ? null : self;
    return isLikeNone(ret) ? 0 : addHeapObject(ret);
}
function __wbg_static_accessor_WINDOW_bb9f1ba69d61b386() {
    const ret = typeof window === 'undefined' ? null : window;
    return isLikeNone(ret) ? 0 : addHeapObject(ret);
}
function __wbg_static_accessor_performance_da77b3a901a72934() {
    const ret = performance;
    return addHeapObject(ret);
}
function __wbg_status_318629ab93a22955(arg0) {
    const ret = getObject(arg0).status;
    return ret;
}
function __wbg_stringify_5ae93966a84901ac() { return handleError(function (arg0) {
    const ret = JSON.stringify(getObject(arg0));
    return addHeapObject(ret);
}, arguments); }
function __wbg_target_7bc90f314634b37b(arg0) {
    const ret = getObject(arg0).target;
    return isLikeNone(ret) ? 0 : addHeapObject(ret);
}
function __wbg_text_372f5b91442c50f9() { return handleError(function (arg0) {
    const ret = getObject(arg0).text();
    return addHeapObject(ret);
}, arguments); }
function __wbg_then_098abe61755d12f6(arg0, arg1) {
    const ret = getObject(arg0).then(getObject(arg1));
    return addHeapObject(ret);
}
function __wbg_then_9e335f6dd892bc11(arg0, arg1, arg2) {
    const ret = getObject(arg0).then(getObject(arg1), getObject(arg2));
    return addHeapObject(ret);
}
function __wbg_transaction_3223f7c8d0f40129() { return handleError(function (arg0, arg1, arg2) {
    const ret = getObject(arg0).transaction(getObject(arg1), __wbindgen_enum_IdbTransactionMode[arg2]);
    return addHeapObject(ret);
}, arguments); }
function __wbg_url_7fefc1820fba4e0c(arg0, arg1) {
    const ret = getObject(arg1).url;
    const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
    const len1 = WASM_VECTOR_LEN;
    getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
    getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
}
function __wbg_user_key_state_716a6e0f86936052(arg0) {
    const ret = getObject(arg0).user_key_state;
    return isLikeNone(ret) ? 0 : addHeapObject(ret);
}
function __wbg_value_21fc78aab0322612(arg0) {
    const ret = getObject(arg0).value;
    return addHeapObject(ret);
}
function __wbg_warn_69424c2d92a2fa73(arg0) {
    console.warn(getObject(arg0));
}
function __wbg_warn_809cad1bfc2b3a42(arg0, arg1, arg2, arg3) {
    console.warn(getObject(arg0), getObject(arg1), getObject(arg2), getObject(arg3));
}
function __wbindgen_cast_0000000000000001(arg0, arg1) {
    // Cast intrinsic for `Closure(Closure { dtor_idx: 198, function: Function { arguments: [NamedExternref("Event")], shim_idx: 199, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
    const ret = makeMutClosure(arg0, arg1, wasm.wasm_bindgen_296f817121844f10___closure__destroy___dyn_core_90c7537bc33d8963___ops__function__FnMut__web_sys_4f71ef441adfe3e1___features__gen_Event__Event____Output_______, wasm_bindgen_296f817121844f10___convert__closures_____invoke___web_sys_4f71ef441adfe3e1___features__gen_Event__Event______true_);
    return addHeapObject(ret);
}
function __wbindgen_cast_0000000000000002(arg0, arg1) {
    // Cast intrinsic for `Closure(Closure { dtor_idx: 340, function: Function { arguments: [Externref], shim_idx: 486, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
    const ret = makeMutClosure(arg0, arg1, wasm.wasm_bindgen_296f817121844f10___closure__destroy___dyn_core_90c7537bc33d8963___ops__function__FnMut__wasm_bindgen_296f817121844f10___JsValue____Output___core_90c7537bc33d8963___result__Result_____wasm_bindgen_296f817121844f10___JsError___, wasm_bindgen_296f817121844f10___convert__closures_____invoke___wasm_bindgen_296f817121844f10___JsValue__core_90c7537bc33d8963___result__Result_____wasm_bindgen_296f817121844f10___JsError___true_);
    return addHeapObject(ret);
}
function __wbindgen_cast_0000000000000003(arg0, arg1) {
    // Cast intrinsic for `Closure(Closure { dtor_idx: 340, function: Function { arguments: [], shim_idx: 362, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
    const ret = makeMutClosure(arg0, arg1, wasm.wasm_bindgen_296f817121844f10___closure__destroy___dyn_core_90c7537bc33d8963___ops__function__FnMut__wasm_bindgen_296f817121844f10___JsValue____Output___core_90c7537bc33d8963___result__Result_____wasm_bindgen_296f817121844f10___JsError___, wasm_bindgen_296f817121844f10___convert__closures_____invoke_______true_);
    return addHeapObject(ret);
}
function __wbindgen_cast_0000000000000004(arg0, arg1) {
    // Cast intrinsic for `Closure(Closure { dtor_idx: 665, function: Function { arguments: [], shim_idx: 362, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.
    const ret = makeMutClosure(arg0, arg1, wasm.wasm_bindgen_296f817121844f10___closure__destroy___dyn_core_90c7537bc33d8963___ops__function__FnMut_____Output_______, wasm_bindgen_296f817121844f10___convert__closures_____invoke_______true_);
    return addHeapObject(ret);
}
function __wbindgen_cast_0000000000000005(arg0) {
    // Cast intrinsic for `F64 -> Externref`.
    const ret = arg0;
    return addHeapObject(ret);
}
function __wbindgen_cast_0000000000000006(arg0) {
    // Cast intrinsic for `I64 -> Externref`.
    const ret = arg0;
    return addHeapObject(ret);
}
function __wbindgen_cast_0000000000000007(arg0, arg1) {
    // Cast intrinsic for `Ref(String) -> Externref`.
    const ret = getStringFromWasm0(arg0, arg1);
    return addHeapObject(ret);
}
function __wbindgen_cast_0000000000000008(arg0) {
    // Cast intrinsic for `U64 -> Externref`.
    const ret = BigInt.asUintN(64, arg0);
    return addHeapObject(ret);
}
function __wbindgen_cast_0000000000000009(arg0, arg1) {
    var v0 = getArrayJsValueFromWasm0(arg0, arg1).slice();
    wasm.__wbindgen_free(arg0, arg1 * 4, 4);
    // Cast intrinsic for `Vector(NamedExternref("CipherListView")) -> Externref`.
    const ret = v0;
    return addHeapObject(ret);
}
function __wbindgen_cast_000000000000000a(arg0, arg1) {
    var v0 = getArrayJsValueFromWasm0(arg0, arg1).slice();
    wasm.__wbindgen_free(arg0, arg1 * 4, 4);
    // Cast intrinsic for `Vector(NamedExternref("CipherRiskResult")) -> Externref`.
    const ret = v0;
    return addHeapObject(ret);
}
function __wbindgen_cast_000000000000000b(arg0, arg1) {
    var v0 = getArrayJsValueFromWasm0(arg0, arg1).slice();
    wasm.__wbindgen_free(arg0, arg1 * 4, 4);
    // Cast intrinsic for `Vector(NamedExternref("CipherView")) -> Externref`.
    const ret = v0;
    return addHeapObject(ret);
}
function __wbindgen_cast_000000000000000c(arg0, arg1) {
    var v0 = getArrayJsValueFromWasm0(arg0, arg1).slice();
    wasm.__wbindgen_free(arg0, arg1 * 4, 4);
    // Cast intrinsic for `Vector(NamedExternref("EncryptionContext")) -> Externref`.
    const ret = v0;
    return addHeapObject(ret);
}
function __wbindgen_cast_000000000000000d(arg0, arg1) {
    var v0 = getArrayJsValueFromWasm0(arg0, arg1).slice();
    wasm.__wbindgen_free(arg0, arg1 * 4, 4);
    // Cast intrinsic for `Vector(NamedExternref("FolderView")) -> Externref`.
    const ret = v0;
    return addHeapObject(ret);
}
function __wbindgen_cast_000000000000000e(arg0, arg1) {
    var v0 = getArrayJsValueFromWasm0(arg0, arg1).slice();
    wasm.__wbindgen_free(arg0, arg1 * 4, 4);
    // Cast intrinsic for `Vector(NamedExternref("SendView")) -> Externref`.
    const ret = v0;
    return addHeapObject(ret);
}
function __wbindgen_cast_000000000000000f(arg0, arg1) {
    var v0 = getArrayJsValueFromWasm0(arg0, arg1).slice();
    wasm.__wbindgen_free(arg0, arg1 * 4, 4);
    // Cast intrinsic for `Vector(NamedExternref("V1EmergencyAccessMembership")) -> Externref`.
    const ret = v0;
    return addHeapObject(ret);
}
function __wbindgen_cast_0000000000000010(arg0, arg1) {
    var v0 = getArrayJsValueFromWasm0(arg0, arg1).slice();
    wasm.__wbindgen_free(arg0, arg1 * 4, 4);
    // Cast intrinsic for `Vector(NamedExternref("V1OrganizationMembership")) -> Externref`.
    const ret = v0;
    return addHeapObject(ret);
}
function __wbindgen_object_clone_ref(arg0) {
    const ret = getObject(arg0);
    return addHeapObject(ret);
}
function __wbindgen_object_drop_ref(arg0) {
    takeObject(arg0);
}
function wasm_bindgen_296f817121844f10___convert__closures_____invoke_______true_(arg0, arg1) {
    wasm.wasm_bindgen_296f817121844f10___convert__closures_____invoke_______true_(arg0, arg1);
}

function wasm_bindgen_296f817121844f10___convert__closures_____invoke___web_sys_4f71ef441adfe3e1___features__gen_Event__Event______true_(arg0, arg1, arg2) {
    wasm.wasm_bindgen_296f817121844f10___convert__closures_____invoke___web_sys_4f71ef441adfe3e1___features__gen_Event__Event______true_(arg0, arg1, addHeapObject(arg2));
}

function wasm_bindgen_296f817121844f10___convert__closures_____invoke___wasm_bindgen_296f817121844f10___JsValue__core_90c7537bc33d8963___result__Result_____wasm_bindgen_296f817121844f10___JsError___true_(arg0, arg1, arg2) {
    try {
        const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
        wasm.wasm_bindgen_296f817121844f10___convert__closures_____invoke___wasm_bindgen_296f817121844f10___JsValue__core_90c7537bc33d8963___result__Result_____wasm_bindgen_296f817121844f10___JsError___true_(retptr, arg0, arg1, addHeapObject(arg2));
        var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
        var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
        if (r1) {
            throw takeObject(r0);
        }
    } finally {
        wasm.__wbindgen_add_to_stack_pointer(16);
    }
}

function wasm_bindgen_296f817121844f10___convert__closures_____invoke___js_sys_b1bce590f5d90a2___Function_fn_wasm_bindgen_296f817121844f10___JsValue_____wasm_bindgen_296f817121844f10___sys__Undefined___js_sys_b1bce590f5d90a2___Function_fn_wasm_bindgen_296f817121844f10___JsValue_____wasm_bindgen_296f817121844f10___sys__Undefined_______true_(arg0, arg1, arg2, arg3) {
    wasm.wasm_bindgen_296f817121844f10___convert__closures_____invoke___js_sys_b1bce590f5d90a2___Function_fn_wasm_bindgen_296f817121844f10___JsValue_____wasm_bindgen_296f817121844f10___sys__Undefined___js_sys_b1bce590f5d90a2___Function_fn_wasm_bindgen_296f817121844f10___JsValue_____wasm_bindgen_296f817121844f10___sys__Undefined_______true_(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));
}


const __wbindgen_enum_IdbTransactionMode = ["readonly", "readwrite", "versionchange", "readwriteflush", "cleanup"];


const __wbindgen_enum_RequestCache = ["default", "no-store", "reload", "no-cache", "force-cache", "only-if-cached"];


const __wbindgen_enum_RequestCredentials = ["omit", "same-origin", "include"];


const __wbindgen_enum_RequestMode = ["same-origin", "no-cors", "cors", "navigate"];
const AttachmentsClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_attachmentsclient_free(ptr >>> 0, 1));
const AuthClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_authclient_free(ptr >>> 0, 1));
const CipherAdminClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_cipheradminclient_free(ptr >>> 0, 1));
const CipherRiskClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_cipherriskclient_free(ptr >>> 0, 1));
const CiphersClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_ciphersclient_free(ptr >>> 0, 1));
const CollectionViewNodeItemFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_collectionviewnodeitem_free(ptr >>> 0, 1));
const CollectionViewTreeFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_collectionviewtree_free(ptr >>> 0, 1));
const CollectionsClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_collectionsclient_free(ptr >>> 0, 1));
const CommercialPasswordManagerClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_commercialpasswordmanagerclient_free(ptr >>> 0, 1));
const CommercialVaultClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_commercialvaultclient_free(ptr >>> 0, 1));
const CryptoClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_cryptoclient_free(ptr >>> 0, 1));
const ExporterClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_exporterclient_free(ptr >>> 0, 1));
const FlightRecorderClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_flightrecorderclient_free(ptr >>> 0, 1));
const FoldersClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_foldersclient_free(ptr >>> 0, 1));
const GeneratorClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_generatorclient_free(ptr >>> 0, 1));
const IncomingMessageFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_incomingmessage_free(ptr >>> 0, 1));
const IpcCommunicationBackendFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_ipccommunicationbackend_free(ptr >>> 0, 1));
const IpcClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_ipcclient_free(ptr >>> 0, 1));
const IpcClientSubscriptionFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_ipcclientsubscription_free(ptr >>> 0, 1));
const ServerCommunicationConfigClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_servercommunicationconfigclient_free(ptr >>> 0, 1));
const LoginClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_loginclient_free(ptr >>> 0, 1));
const OutgoingMessageFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_outgoingmessage_free(ptr >>> 0, 1));
const PasswordManagerClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_passwordmanagerclient_free(ptr >>> 0, 1));
const PlatformClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_platformclient_free(ptr >>> 0, 1));
const PureCryptoFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_purecrypto_free(ptr >>> 0, 1));
const RegistrationClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_registrationclient_free(ptr >>> 0, 1));
const SendAccessClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_sendaccessclient_free(ptr >>> 0, 1));
const SendClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_sendclient_free(ptr >>> 0, 1));
const StateClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_stateclient_free(ptr >>> 0, 1));
const TotpClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_totpclient_free(ptr >>> 0, 1));
const UserCryptoManagementClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_usercryptomanagementclient_free(ptr >>> 0, 1));
const VaultClientFinalization = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(ptr => wasm.__wbg_vaultclient_free(ptr >>> 0, 1));

function addHeapObject(obj) {
    if (heap_next === heap.length) heap.push(heap.length + 1);
    const idx = heap_next;
    heap_next = heap[idx];

    heap[idx] = obj;
    return idx;
}

function _assertClass(instance, klass) {
    if (!(instance instanceof klass)) {
        throw new Error(`expected instance of ${klass.name}`);
    }
}

function addBorrowedObject(obj) {
    if (stack_pointer == 1) throw new Error('out of js stack');
    heap[--stack_pointer] = obj;
    return stack_pointer;
}

const CLOSURE_DTORS = (typeof FinalizationRegistry === 'undefined')
    ? { register: () => {}, unregister: () => {} }
    : new FinalizationRegistry(state => state.dtor(state.a, state.b));

function debugString(val) {
    // primitive types
    const type = typeof val;
    if (type == 'number' || type == 'boolean' || val == null) {
        return  `${val}`;
    }
    if (type == 'string') {
        return `"${val}"`;
    }
    if (type == 'symbol') {
        const description = val.description;
        if (description == null) {
            return 'Symbol';
        } else {
            return `Symbol(${description})`;
        }
    }
    if (type == 'function') {
        const name = val.name;
        if (typeof name == 'string' && name.length > 0) {
            return `Function(${name})`;
        } else {
            return 'Function';
        }
    }
    // objects
    if (Array.isArray(val)) {
        const length = val.length;
        let debug = '[';
        if (length > 0) {
            debug += debugString(val[0]);
        }
        for(let i = 1; i < length; i++) {
            debug += ', ' + debugString(val[i]);
        }
        debug += ']';
        return debug;
    }
    // Test for built-in
    const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val));
    let className;
    if (builtInMatches && builtInMatches.length > 1) {
        className = builtInMatches[1];
    } else {
        // Failed to match the standard '[object ClassName]'
        return toString.call(val);
    }
    if (className == 'Object') {
        // we're a user defined class or Object
        // JSON.stringify avoids problems with cycles, and is generally much
        // easier than looping through ownProperties of `val`.
        try {
            return 'Object(' + JSON.stringify(val) + ')';
        } catch (_) {
            return 'Object';
        }
    }
    // errors
    if (val instanceof Error) {
        return `${val.name}: ${val.message}\n${val.stack}`;
    }
    // TODO we could test for more things here, like `Set`s and `Map`s.
    return className;
}

function dropObject(idx) {
    if (idx < 1028) return;
    heap[idx] = heap_next;
    heap_next = idx;
}

function getArrayJsValueFromWasm0(ptr, len) {
    ptr = ptr >>> 0;
    const mem = getDataViewMemory0();
    const result = [];
    for (let i = ptr; i < ptr + 4 * len; i += 4) {
        result.push(takeObject(mem.getUint32(i, true)));
    }
    return result;
}

function getArrayU8FromWasm0(ptr, len) {
    ptr = ptr >>> 0;
    return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
}

let cachedDataViewMemory0 = null;
function getDataViewMemory0() {
    if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
        cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
    }
    return cachedDataViewMemory0;
}

function getStringFromWasm0(ptr, len) {
    ptr = ptr >>> 0;
    return decodeText(ptr, len);
}

let cachedUint8ArrayMemory0 = null;
function getUint8ArrayMemory0() {
    if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
        cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
    }
    return cachedUint8ArrayMemory0;
}

function getObject(idx) { return heap[idx]; }

function handleError(f, args) {
    try {
        return f.apply(this, args);
    } catch (e) {
        wasm.__wbindgen_exn_store(addHeapObject(e));
    }
}

let heap = new Array(1024).fill(undefined);
heap.push(undefined, null, true, false);

let heap_next = heap.length;

function isLikeNone(x) {
    return x === undefined || x === null;
}

function makeMutClosure(arg0, arg1, dtor, f) {
    const state = { a: arg0, b: arg1, cnt: 1, dtor };
    const real = (...args) => {

        // First up with a closure we increment the internal reference
        // count. This ensures that the Rust closure environment won't
        // be deallocated while we're invoking it.
        state.cnt++;
        const a = state.a;
        state.a = 0;
        try {
            return f(a, state.b, ...args);
        } finally {
            state.a = a;
            real._wbg_cb_unref();
        }
    };
    real._wbg_cb_unref = () => {
        if (--state.cnt === 0) {
            state.dtor(state.a, state.b);
            state.a = 0;
            CLOSURE_DTORS.unregister(state);
        }
    };
    CLOSURE_DTORS.register(real, state, state);
    return real;
}

function passArray8ToWasm0(arg, malloc) {
    const ptr = malloc(arg.length * 1, 1) >>> 0;
    getUint8ArrayMemory0().set(arg, ptr / 1);
    WASM_VECTOR_LEN = arg.length;
    return ptr;
}

function passArrayJsValueToWasm0(array, malloc) {
    const ptr = malloc(array.length * 4, 4) >>> 0;
    const mem = getDataViewMemory0();
    for (let i = 0; i < array.length; i++) {
        mem.setUint32(ptr + 4 * i, addHeapObject(array[i]), true);
    }
    WASM_VECTOR_LEN = array.length;
    return ptr;
}

function passStringToWasm0(arg, malloc, realloc) {
    if (realloc === undefined) {
        const buf = cachedTextEncoder.encode(arg);
        const ptr = malloc(buf.length, 1) >>> 0;
        getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
        WASM_VECTOR_LEN = buf.length;
        return ptr;
    }

    let len = arg.length;
    let ptr = malloc(len, 1) >>> 0;

    const mem = getUint8ArrayMemory0();

    let offset = 0;

    for (; offset < len; offset++) {
        const code = arg.charCodeAt(offset);
        if (code > 0x7F) break;
        mem[ptr + offset] = code;
    }
    if (offset !== len) {
        if (offset !== 0) {
            arg = arg.slice(offset);
        }
        ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
        const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
        const ret = cachedTextEncoder.encodeInto(arg, view);

        offset += ret.written;
        ptr = realloc(ptr, len, offset, 1) >>> 0;
    }

    WASM_VECTOR_LEN = offset;
    return ptr;
}

let stack_pointer = 1024;

function takeObject(idx) {
    const ret = getObject(idx);
    dropObject(idx);
    return ret;
}

let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
cachedTextDecoder.decode();
const MAX_SAFARI_DECODE_BYTES = 2146435072;
let numBytesDecoded = 0;
function decodeText(ptr, len) {
    numBytesDecoded += len;
    if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {
        cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
        cachedTextDecoder.decode();
        numBytesDecoded = len;
    }
    return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
}

const cachedTextEncoder = new TextEncoder();

if (!('encodeInto' in cachedTextEncoder)) {
    cachedTextEncoder.encodeInto = function (arg, view) {
        const buf = cachedTextEncoder.encode(arg);
        view.set(buf);
        return {
            read: arg.length,
            written: buf.length
        };
    };
}

let WASM_VECTOR_LEN = 0;


let wasm;
function __wbg_set_wasm(val) {
    wasm = val;
}


/***/ },

/***/ 857
(module) {

module.exports = require("url");

/***/ }

/******/ 	});
/************************************************************************/
/******/ 	// The module cache
/******/ 	var __webpack_module_cache__ = {};
/******/ 	
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/ 		// Check if module is in cache
/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
/******/ 		if (cachedModule !== undefined) {
/******/ 			return cachedModule.exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = __webpack_module_cache__[moduleId] = {
/******/ 			id: moduleId,
/******/ 			// no module.loaded needed
/******/ 			exports: {}
/******/ 		};
/******/ 	
/******/ 		// Execute the module function
/******/ 		__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/ 	
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/ 	
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = __webpack_modules__;
/******/ 	
/************************************************************************/
/******/ 	/* webpack/runtime/compat get default export */
/******/ 	(() => {
/******/ 		// getDefaultExport function for compatibility with non-harmony modules
/******/ 		__webpack_require__.n = (module) => {
/******/ 			var getter = module && module.__esModule ?
/******/ 				() => (module['default']) :
/******/ 				() => (module);
/******/ 			__webpack_require__.d(getter, { a: getter });
/******/ 			return getter;
/******/ 		};
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/define property getters */
/******/ 	(() => {
/******/ 		// define getter functions for harmony exports
/******/ 		__webpack_require__.d = (exports, definition) => {
/******/ 			for(var key in definition) {
/******/ 				if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ 					Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ 				}
/******/ 			}
/******/ 		};
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/ensure chunk */
/******/ 	(() => {
/******/ 		__webpack_require__.f = {};
/******/ 		// This file contains only the entry chunk.
/******/ 		// The chunk loading function for additional chunks
/******/ 		__webpack_require__.e = (chunkId) => {
/******/ 			return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
/******/ 				__webpack_require__.f[key](chunkId, promises);
/******/ 				return promises;
/******/ 			}, []));
/******/ 		};
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/get javascript chunk filename */
/******/ 	(() => {
/******/ 		// This function allow to reference async chunks
/******/ 		__webpack_require__.u = (chunkId) => {
/******/ 			// return url for filenames based on template
/******/ 			return "" + chunkId + ".js";
/******/ 		};
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/hasOwnProperty shorthand */
/******/ 	(() => {
/******/ 		__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/make namespace object */
/******/ 	(() => {
/******/ 		// define __esModule on exports
/******/ 		__webpack_require__.r = (exports) => {
/******/ 			if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 				Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 			}
/******/ 			Object.defineProperty(exports, '__esModule', { value: true });
/******/ 		};
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/wasm loading */
/******/ 	(() => {
/******/ 		__webpack_require__.v = (exports, wasmModuleId, wasmModuleHash, importsObj) => {
/******/ 		
/******/ 			return new Promise(function (resolve, reject) {
/******/ 				try {
/******/ 					var { readFile } = require("node:fs");
/******/ 					var { join } = require("node:path");
/******/ 		
/******/ 					readFile(join(__dirname, "" + wasmModuleHash + ".module.wasm"), function(err, buffer){
/******/ 						if (err) return reject(err);
/******/ 		
/******/ 						// Fake fetch response
/******/ 						resolve({
/******/ 							arrayBuffer() { return buffer; }
/******/ 						});
/******/ 					});
/******/ 				} catch (err) { reject(err); }
/******/ 			})
/******/ 				.then((x) => (x.arrayBuffer()))
/******/ 				.then((bytes) => (WebAssembly.instantiate(bytes, importsObj)))
/******/ 				.then((res) => (Object.assign(exports, res.instance.exports)));
/******/ 		};
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/require chunk loading */
/******/ 	(() => {
/******/ 		// no baseURI
/******/ 		
/******/ 		// object to store loaded chunks
/******/ 		// "1" means "loaded", otherwise not loaded yet
/******/ 		var installedChunks = {
/******/ 			570: 1
/******/ 		};
/******/ 		
/******/ 		// no on chunks loaded
/******/ 		
/******/ 		var installChunk = (chunk) => {
/******/ 			var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime;
/******/ 			for(var moduleId in moreModules) {
/******/ 				if(__webpack_require__.o(moreModules, moduleId)) {
/******/ 					__webpack_require__.m[moduleId] = moreModules[moduleId];
/******/ 				}
/******/ 			}
/******/ 			if(runtime) runtime(__webpack_require__);
/******/ 			for(var i = 0; i < chunkIds.length; i++)
/******/ 				installedChunks[chunkIds[i]] = 1;
/******/ 		
/******/ 		};
/******/ 		
/******/ 		// require() chunk loading for javascript
/******/ 		__webpack_require__.f.require = (chunkId, promises) => {
/******/ 			// "1" is the signal for "already loaded"
/******/ 			if(!installedChunks[chunkId]) {
/******/ 				if(true) { // all chunks have JS
/******/ 					var installedChunk = require("./" + __webpack_require__.u(chunkId));
/******/ 					if (!installedChunks[chunkId]) {
/******/ 						installChunk(installedChunk);
/******/ 					}
/******/ 				} else installedChunks[chunkId] = 1;
/******/ 			}
/******/ 		};
/******/ 		
/******/ 		// no external install chunk
/******/ 		
/******/ 		// no HMR
/******/ 		
/******/ 		// no HMR manifest
/******/ 	})();
/******/ 	
/************************************************************************/
var __webpack_exports__ = {};

// NAMESPACE OBJECT: ../../libs/tools/generator/core/src/engine/index.ts
var engine_namespaceObject = {};
__webpack_require__.r(engine_namespaceObject);
__webpack_require__.d(engine_namespaceObject, {
  Lq: () => (EmailCalculator),
  Mt: () => (EmailRandomizer),
  sF: () => (forwarder_context_ForwarderContext),
  Zx: () => (PasswordRandomizer),
  f3: () => (purecrypto_randomizer_PureCryptoRandomizer),
  zT: () => (SdkPasswordRandomizer),
  QS: () => (UsernameRandomizer)
});

// NAMESPACE OBJECT: ../../libs/tools/generator/core/src/strategies/index.ts
var strategies_namespaceObject = {};
__webpack_require__.r(strategies_namespaceObject);
__webpack_require__.d(strategies_namespaceObject, {
  B: () => (CatchallGeneratorStrategy),
  KQ: () => (EffUsernameGeneratorStrategy),
  ji: () => (ForwarderGeneratorStrategy),
  jK: () => (PassphraseGeneratorStrategy),
  gb: () => (PasswordGeneratorStrategy),
  Vm: () => (SubaddressGeneratorStrategy)
});

;// external "core-js/proposals/explicit-resource-management"
const explicit_resource_management_namespaceObject = require("core-js/proposals/explicit-resource-management");
;// external "commander"
const external_commander_namespaceObject = require("commander");
;// external "chalk"
const external_chalk_namespaceObject = require("chalk");
;// external "rxjs"
const external_rxjs_namespaceObject = require("rxjs");
;// ../../libs/common/src/auth/enums/authentication-status.ts
/**
 * The authentication status of the user
 *
 * See `AuthService.authStatusFor$` for details on how we determine the user's `AuthenticationStatus`
 */
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var authentication_status_AuthenticationStatus;
(function (AuthenticationStatus) {
    /**
     * User is not authenticated
     *  - The user does not have an active account userId and/or an access token in state
     */
    AuthenticationStatus[AuthenticationStatus["LoggedOut"] = 0] = "LoggedOut";
    /**
     * User is authenticated but not decrypted
     *  - The user has an access token, but no user key in state
     *  - Vault data cannot be decrypted (because there is no user key)
     */
    AuthenticationStatus[AuthenticationStatus["Locked"] = 1] = "Locked";
    /**
     * User is authenticated and decrypted
     *  - The user has an access token and a user key in state
     *  - Vault data can be decrypted (via user key)
     */
    AuthenticationStatus[AuthenticationStatus["Unlocked"] = 2] = "Unlocked";
})(authentication_status_AuthenticationStatus || (authentication_status_AuthenticationStatus = {}));

;// external "path"
const external_path_namespaceObject = require("path");
;// external "buffer/"
const _namespaceObject = require("buffer/");
;// external "tldts"
const external_tldts_namespaceObject = require("tldts");
;// external "core-js/proposals/array-buffer-base64"
const array_buffer_base64_namespaceObject = require("core-js/proposals/array-buffer-base64");
;// ../../libs/common/src/platform/misc/utils.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
/* eslint-disable no-useless-escape */





// FIXME: Remove when updating file. Eslint update
// eslint-disable-next-line @typescript-eslint/no-require-imports
const nodeURL = typeof self === "undefined" ? __webpack_require__(857) : null;
// Checked against the result of decodeURIComponent(url). Literal entries catch
// single-encoded input (%2e%2e → ".." after decode). Percent-encoded entries catch
// double-encoded input (%252e → "%2e" after one decode, matched literally here).
const pathTraversalPatterns = [
    "..", // Double dot
    "%2e", // Double-encoded single dot (%252e → "%2e")
    "\\", // Backslash
    "%5c", // Double-encoded backslash (%255c → "%5c")
    "\t", // TAB (stripped by WHATWG URL parser)
    "%09", // Double-encoded TAB (%2509 → "%09")
    "\n", // Line feed (stripped by WHATWG URL parser)
    "%0a", // Double-encoded line feed (%250a → "%0a")
    "\r", // Carriage return (stripped by WHATWG URL parser)
    "%0d", // Double-encoded carriage return (%250d → "%0d")
    "\0", // Null byte
    "%00", // Double-encoded null byte (%2500 → "%00")
];
// Query-string-specific patterns, also checked after decodeURIComponent.
const queryDangerousPatterns = [
    "/", // Path separator (Dangerous in a query parameter)
    "%2f", // Double-encoded path separator (%252f → "%2f")
    "#", // Fragment delimiter (Truncates strings)
    "%23", // Double-encoded fragment delimiter (%2523 → "%23")
];
class utils_Utils {
    static init() {
        if (utils_Utils.inited) {
            return;
        }
        utils_Utils.inited = true;
        utils_Utils.isNode =
            typeof process !== "undefined" &&
                process.release != null &&
                process.release.name === "node";
        utils_Utils.isBrowser = typeof window !== "undefined";
        utils_Utils.isMobileBrowser = utils_Utils.isBrowser && this.isMobile(window);
        utils_Utils.isAppleMobileBrowser = utils_Utils.isBrowser && this.isAppleMobile(window);
        if (utils_Utils.isNode) {
            utils_Utils.global = global;
        }
        else if (utils_Utils.isBrowser) {
            utils_Utils.global = window;
        }
        else {
            // If it's not browser or node then it must be a service worker
            utils_Utils.global = self;
        }
    }
    static fromB64ToArray(str) {
        if (str == null) {
            return null;
        }
        if (utils_Utils.isNode) {
            return new Uint8Array(Buffer.from(str, "base64"));
        }
        else {
            const binaryString = utils_Utils.global.atob(str);
            const bytes = new Uint8Array(binaryString.length);
            for (let i = 0; i < binaryString.length; i++) {
                bytes[i] = binaryString.charCodeAt(i);
            }
            return bytes;
        }
    }
    static fromUrlB64ToArray(str) {
        return utils_Utils.fromB64ToArray(utils_Utils.fromUrlB64ToB64(str));
    }
    static fromHexToArray(str) {
        if (utils_Utils.isNode) {
            return new Uint8Array(Buffer.from(str, "hex"));
        }
        else {
            const bytes = new Uint8Array(str.length / 2);
            for (let i = 0; i < str.length; i += 2) {
                bytes[i / 2] = parseInt(str.substr(i, 2), 16);
            }
            return bytes;
        }
    }
    static fromUtf8ToArray(str) {
        if (utils_Utils.isNode) {
            return new Uint8Array(Buffer.from(str, "utf8"));
        }
        else {
            const strUtf8 = unescape(encodeURIComponent(str));
            const arr = new Uint8Array(strUtf8.length);
            for (let i = 0; i < strUtf8.length; i++) {
                arr[i] = strUtf8.charCodeAt(i);
            }
            return arr;
        }
    }
    static fromByteStringToArray(str) {
        if (str == null) {
            return null;
        }
        const arr = new Uint8Array(str.length);
        for (let i = 0; i < str.length; i++) {
            arr[i] = str.charCodeAt(i);
        }
        return arr;
    }
    /**
     * Converts a Uint8Array to a hexadecimal string.
     * @param arr - The Uint8Array to convert.
     * @returns The hexadecimal string representation, or null if the input is null.
     */
    static fromArrayToHex(arr) {
        if (arr == null) {
            return null;
        }
        // @ts-expect-error - polyfilled by core-js
        return arr.toHex();
    }
    /**
     * Converts a Uint8Array to a Base64 encoded string.
     * @param arr - The Uint8Array to convert.
     * @returns The Base64 encoded string, or null if the input is null.
     */
    static fromArrayToB64(arr) {
        if (arr == null) {
            return null;
        }
        // @ts-expect-error - polyfilled by core-js
        return arr.toBase64({ alphabet: "base64" });
    }
    static fromArrayToUrlB64(arr) {
        if (arr == null) {
            return null;
        }
        // @ts-expect-error - polyfilled by core-js
        return arr.toBase64({ alphabet: "base64url", omitPadding: true });
    }
    /**
     * Converts a Uint8Array to a byte string (each byte as a character).
     * @param arr - The Uint8Array to convert.
     * @returns The byte string representation, or null if the input is null.
     */
    static fromArrayToByteString(arr) {
        if (arr == null) {
            return null;
        }
        let byteString = "";
        for (let i = 0; i < arr.length; i++) {
            byteString += String.fromCharCode(arr[i]);
        }
        return byteString;
    }
    /**
     * Converts a Uint8Array to a UTF-8 decoded string.
     * @param arr - The Uint8Array containing UTF-8 encoded bytes.
     * @returns The decoded UTF-8 string, or null if the input is null.
     */
    static fromArrayToUtf8(arr) {
        if (arr == null) {
            return null;
        }
        return _namespaceObject.Buffer.from(arr).toString("utf8");
    }
    static fromBufferToB64(buffer) {
        // Handle null / undefined input
        if (buffer == null) {
            return null;
        }
        const bytes = utils_Utils.normalizeToUint8Array(buffer);
        // Handle empty input
        if (bytes.length === 0) {
            return "";
        }
        if (utils_Utils.isNode) {
            return Buffer.from(bytes).toString("base64");
        }
        else {
            let binary = "";
            for (let i = 0; i < bytes.byteLength; i++) {
                binary += String.fromCharCode(bytes[i]);
            }
            return utils_Utils.global.btoa(binary);
        }
    }
    /**
     * Normalizes input into a Uint8Array so we always have a uniform,
     * byte-level view of the data. This avoids dealing with differences
     * between ArrayBuffer (raw memory with no indexing) and other typed
     * views (which may have element sizes, offsets, and lengths).
     * @param buffer ArrayBuffer or ArrayBufferView (e.g. Uint8Array, DataView, etc.)
     */
    static normalizeToUint8Array(buffer) {
        /**
         * 1) Uint8Array: already bytes → use directly.
         * 2) ArrayBuffer: wrap whole buffer.
         * 3) Other ArrayBufferView (e.g., DataView, Int32Array):
         *    wrap the view’s window (byteOffset..byteOffset+byteLength).
         */
        if (buffer instanceof Uint8Array) {
            return buffer;
        }
        else if (buffer instanceof ArrayBuffer) {
            return new Uint8Array(buffer);
        }
        else {
            const view = buffer;
            return new Uint8Array(view.buffer, view.byteOffset, view.byteLength);
        }
    }
    static fromBufferToUrlB64(buffer) {
        return utils_Utils.fromB64toUrlB64(utils_Utils.fromBufferToB64(buffer));
    }
    static fromB64toUrlB64(b64Str) {
        return b64Str.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
    }
    static fromBufferToUtf8(buffer) {
        return _namespaceObject.Buffer.from(buffer).toString("utf8");
    }
    static fromBufferToByteString(buffer) {
        return String.fromCharCode.apply(null, new Uint8Array(buffer));
    }
    // ref: https://stackoverflow.com/a/40031979/1090359
    static fromBufferToHex(buffer) {
        if (utils_Utils.isNode) {
            return Buffer.from(buffer).toString("hex");
        }
        else {
            const bytes = new Uint8Array(buffer);
            return Array.prototype.map
                .call(bytes, (x) => ("00" + x.toString(16)).slice(-2))
                .join("");
        }
    }
    /**
     * Converts a hex string to an ArrayBuffer.
     * Note: this doesn't need any Node specific code as parseInt() / ArrayBuffer / Uint8Array
     * work the same in Node and the browser.
     * @param {string} hexString - A string of hexadecimal characters.
     * @returns {ArrayBuffer} The ArrayBuffer representation of the hex string.
     */
    static hexStringToArrayBuffer(hexString) {
        // Check if the hexString has an even length, as each hex digit represents half a byte (4 bits),
        // and it takes two hex digits to represent a full byte (8 bits).
        if (hexString.length % 2 !== 0) {
            throw "HexString has to be an even length";
        }
        // Create an ArrayBuffer with a length that is half the length of the hex string,
        // because each pair of hex digits will become a single byte.
        const arrayBuffer = new ArrayBuffer(hexString.length / 2);
        // Create a Uint8Array view on top of the ArrayBuffer (each position represents a byte)
        // as ArrayBuffers cannot be edited directly.
        const uint8Array = new Uint8Array(arrayBuffer);
        // Loop through the bytes
        for (let i = 0; i < uint8Array.length; i++) {
            // Extract two hex characters (1 byte)
            const hexByte = hexString.substr(i * 2, 2);
            // Convert hexByte into a decimal value from base 16. (ex: ff --> 255)
            const byteValue = parseInt(hexByte, 16);
            // Place the byte value into the uint8Array
            uint8Array[i] = byteValue;
        }
        return arrayBuffer;
    }
    static fromUrlB64ToB64(urlB64Str) {
        let output = urlB64Str.replace(/-/g, "+").replace(/_/g, "/");
        switch (output.length % 4) {
            case 0:
                break;
            case 2:
                output += "==";
                break;
            case 3:
                output += "=";
                break;
            default:
                throw new Error("Illegal base64url string!");
        }
        return output;
    }
    static fromUrlB64ToUtf8(urlB64Str) {
        return utils_Utils.fromB64ToUtf8(utils_Utils.fromUrlB64ToB64(urlB64Str));
    }
    static fromUtf8ToB64(utfStr) {
        if (utils_Utils.isNode) {
            return Buffer.from(utfStr, "utf8").toString("base64");
        }
        else {
            return _namespaceObject.Buffer.from(utfStr, "utf8").toString("base64");
        }
    }
    static fromUtf8ToUrlB64(utfStr) {
        return utils_Utils.fromArrayToUrlB64(utils_Utils.fromUtf8ToArray(utfStr));
    }
    static fromB64ToUtf8(b64Str) {
        if (utils_Utils.isNode) {
            return Buffer.from(b64Str, "base64").toString("utf8");
        }
        else {
            return _namespaceObject.Buffer.from(b64Str, "base64").toString("utf8");
        }
    }
    // ref: http://stackoverflow.com/a/2117523/1090359
    /** @deprecated Use newGuid from @bitwarden/guid instead */
    static newGuid() {
        return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
            const r = (Math.random() * 16) | 0;
            const v = c === "x" ? r : (r & 0x3) | 0x8;
            return v.toString(16);
        });
    }
    /** @deprecated Use isGuid from @bitwarden/guid instead */
    static isGuid(id) {
        return RegExp(utils_Utils.guidRegex, "i").test(id);
    }
    static getHostname(uriString) {
        if (utils_Utils.isNullOrWhitespace(uriString)) {
            return null;
        }
        uriString = uriString.trim();
        if (uriString.startsWith("data:")) {
            return null;
        }
        if (uriString.startsWith("about:")) {
            return null;
        }
        if (uriString.startsWith("file:")) {
            return null;
        }
        try {
            const hostname = (0,external_tldts_namespaceObject.getHostname)(uriString, { validHosts: this.validHosts });
            if (hostname != null) {
                return hostname;
            }
        }
        catch (_a) {
            return null;
        }
        return null;
    }
    static getHost(uriString) {
        const url = utils_Utils.getUrl(uriString);
        try {
            return url != null && url.host !== "" ? url.host : null;
        }
        catch (_a) {
            return null;
        }
    }
    static getDomain(uriString) {
        if (utils_Utils.isNullOrWhitespace(uriString)) {
            return null;
        }
        uriString = uriString.trim();
        if (uriString.startsWith("data:")) {
            return null;
        }
        if (uriString.startsWith("about:")) {
            return null;
        }
        try {
            const parseResult = (0,external_tldts_namespaceObject.parse)(uriString, {
                validHosts: this.validHosts,
                allowPrivateDomains: true,
            });
            if (parseResult != null && parseResult.hostname != null) {
                if (parseResult.hostname === "localhost" || parseResult.isIp) {
                    return parseResult.hostname;
                }
                if (parseResult.domain != null) {
                    return parseResult.domain;
                }
                return null;
            }
        }
        catch (_a) {
            return null;
        }
        return null;
    }
    static getQueryParams(uriString) {
        const url = utils_Utils.getUrl(uriString);
        if (url == null || url.search == null || url.search === "") {
            return null;
        }
        const map = new Map();
        const pairs = (url.search[0] === "?" ? url.search.substr(1) : url.search).split("&");
        pairs.forEach((pair) => {
            const parts = pair.split("=");
            if (parts.length < 1) {
                return;
            }
            map.set(decodeURIComponent(parts[0]).toLowerCase(), parts[1] == null ? "" : decodeURIComponent(parts[1]));
        });
        return map;
    }
    static getSortFunction(i18nService, prop) {
        return (a, b) => {
            if (a[prop] == null && b[prop] != null) {
                return -1;
            }
            if (a[prop] != null && b[prop] == null) {
                return 1;
            }
            if (a[prop] == null && b[prop] == null) {
                return 0;
            }
            // The `as unknown as string` here is unfortunate because typescript doesn't property understand that the return of T[prop] will be a string
            return i18nService.collator
                ? i18nService.collator.compare(a[prop], b[prop])
                : a[prop].localeCompare(b[prop]);
        };
    }
    static isNullOrWhitespace(str) {
        return str == null || typeof str !== "string" || str.trim() === "";
    }
    static isNullOrEmpty(str) {
        return str == null || typeof str !== "string" || str == "";
    }
    static isPromise(obj) {
        return (obj != undefined && typeof obj["then"] === "function" && typeof obj["catch"] === "function");
    }
    static nameOf(name) {
        return name;
    }
    static assign(target, source) {
        return Object.assign(target, source);
    }
    static iterateEnum(obj) {
        return Object.keys(obj).filter((k) => Number.isNaN(+k)).map((k) => obj[k]);
    }
    static getUrl(uriString) {
        if (this.isNullOrWhitespace(uriString)) {
            return null;
        }
        uriString = uriString.trim();
        return utils_Utils.getUrlObject(uriString);
    }
    static camelToPascalCase(s) {
        return s.charAt(0).toUpperCase() + s.slice(1);
    }
    /**
     * There are a few ways to calculate text color for contrast, this one seems to fit accessibility guidelines best.
     * https://stackoverflow.com/a/3943023/6869691
     *
     * @param {string} bgColor
     * @param {number} [threshold] see stackoverflow link above
     * @param {boolean} [svgTextFill]
     * Indicates if this method is performed on an SVG <text> 'fill' attribute (e.g. <text fill="black"></text>).
     * This check is necessary because the '!important' tag cannot be used in a 'fill' attribute.
     */
    static pickTextColorBasedOnBgColor(bgColor, threshold = 186, svgTextFill = false) {
        const bgColorHexNums = bgColor.charAt(0) === "#" ? bgColor.substring(1, 7) : bgColor;
        const r = parseInt(bgColorHexNums.substring(0, 2), 16); // hexToR
        const g = parseInt(bgColorHexNums.substring(2, 4), 16); // hexToG
        const b = parseInt(bgColorHexNums.substring(4, 6), 16); // hexToB
        const blackColor = svgTextFill ? "black" : "black !important";
        const whiteColor = svgTextFill ? "white" : "white !important";
        return r * 0.299 + g * 0.587 + b * 0.114 > threshold ? blackColor : whiteColor;
    }
    static stringToColor(str) {
        let hash = 0;
        for (let i = 0; i < str.length; i++) {
            hash = str.charCodeAt(i) + ((hash << 5) - hash);
        }
        let color = "#";
        for (let i = 0; i < 3; i++) {
            const value = (hash >> (i * 8)) & 0xff;
            color += ("00" + value.toString(16)).substr(-2);
        }
        return color;
    }
    /**
     * @throws Will throw an error if the ContainerService has not been attached to the window object
     */
    static getContainerService() {
        if (this.global.bitwardenContainerService == null) {
            throw new Error("global bitwardenContainerService not initialized.");
        }
        return this.global.bitwardenContainerService;
    }
    static validateHexColor(color) {
        return /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(color);
    }
    /**
     * Converts map to a Record<string, V> with the same data. Inverse of recordToMap
     * Useful in toJSON methods, since Maps are not serializable
     * @param map
     * @returns
     */
    static mapToRecord(map) {
        if (map == null) {
            return null;
        }
        if (!(map instanceof Map)) {
            return map;
        }
        return Object.fromEntries(map);
    }
    /**
     * Converts record to a Map<string, V> with the same data. Inverse of mapToRecord
     * Useful in fromJSON methods, since Maps are not serializable
     *
     * Warning: If the record has string keys that are numbers, they will be converted to numbers in the map
     * @param record
     * @returns
     */
    static recordToMap(record) {
        if (record == null) {
            return null;
        }
        else if (record instanceof Map) {
            return record;
        }
        const entries = Object.entries(record);
        if (entries.length === 0) {
            return new Map();
        }
        if (isNaN(Number(entries[0][0]))) {
            return new Map(entries);
        }
        else {
            return new Map(entries.map((e) => [Number(e[0]), e[1]]));
        }
    }
    /** Applies Object.assign, but converts the type nicely using Type-Fest Merge<Destination, Source> */
    static merge(destination, source) {
        return Object.assign(destination, source);
    }
    /**
     * encodeURIComponent escapes all characters except the following:
     * alphabetic, decimal digits, - _ . ! ~ * ' ( )
     * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent#encoding_for_rfc3986
     */
    static encodeRFC3986URIComponent(str) {
        return encodeURIComponent(str).replace(/[!'()*]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);
    }
    /**
     * Normalizes a path for defense against attacks like traversals
     * @param denormalizedPath
     * @returns
     */
    static normalizePath(denormalizedPath) {
        return external_path_namespaceObject.normalize(decodeURIComponent(denormalizedPath)).replace(/^(\.\.(\/|\\|$))+/, "");
    }
    /**
     * Checks whether a URL string contains common path traversal indicators.
     *
     * This is a **supplementary heuristic**, not a security boundary.
     *
     * Primary defense against untrusted input in URL paths is
     * validation at the input boundary (component level).
     * Companion sanitizer: {@link normalizePath}.
     *
     * Known limitations:
     * - This is a denylist, NOT a substitute for boundary validation.
     * - WHATWG URL normalization may alter byte sequences beyond the checked set.
     *
     * @param url - The full URL string to inspect (path + optional query string).
     * @returns `true` if traversal indicators are found; `false` otherwise.
     */
    static containsTraversalIndicators(url) {
        let decodedUrl;
        try {
            decodedUrl = decodeURIComponent(url.toLowerCase());
        }
        catch (_a) {
            // Malformed URI sequences (e.g., overlong UTF-8) are treated as suspicious.
            return true;
        }
        if (pathTraversalPatterns.some((p) => decodedUrl.includes(p))) {
            return true;
        }
        if (decodedUrl.includes("?")) {
            return this.containsDangerousQueryPatterns(decodedUrl);
        }
        return false;
    }
    /**
     * Checks whether query parameters contain characters that could indicate
     * path injection within a query string context.
     *
     * Note: When called from {@link containsTraversalIndicators}, the URL has
     * already been decoded via `decodeURIComponent`. The encoded forms (`%2f`,
     * `%23`) in the pattern list are therefore redundant in that context — the
     * literal `/` and `#` entries handle matching. The encoded forms are retained
     * for clarity and in case this method is called on non-decoded input.
     *
     * @param url - A URL string containing a query string (after `?`).
     * @returns `true` if dangerous patterns are found in the query string; `false` otherwise.
     */
    static containsDangerousQueryPatterns(url) {
        const queryString = url.split("?")[1];
        if (!queryString) {
            return false;
        }
        return queryDangerousPatterns.some((p) => queryString.includes(p));
    }
    static isMobile(win) {
        let mobile = false;
        ((a) => {
            if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) ||
                /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) {
                mobile = true;
            }
        })(win.navigator.userAgent || win.navigator.vendor || win.opera);
        return mobile || win.navigator.userAgent.match(/iPad/i) != null;
    }
    static delay(ms) {
        return new Promise((resolve) => setTimeout(resolve, ms));
    }
    /**
     * Generate an observable from a function that returns a promise.
     * Similar to the rxjs function {@link from} with one big exception:
     * {@link from} will not re-execute the function when observers resubscribe.
     * {@link Util.asyncToObservable} will execute `generator` for every
     * subscribe, making it ideal if the value ever needs to be refreshed.
     * */
    static asyncToObservable(generator) {
        return (0,external_rxjs_namespaceObject.of)(undefined).pipe((0,external_rxjs_namespaceObject.switchMap)(() => generator()));
    }
    /**
     * Return the number of days remaining before a target date arrives.
     * Returns 0 if the day has already passed.
     */
    static daysRemaining(targetDate) {
        const diffTime = targetDate.getTime() - Date.now();
        const msPerDay = 86400000;
        return Math.max(0, Math.floor(diffTime / msPerDay));
    }
    static isAppleMobile(win) {
        return (win.navigator.userAgent.match(/iPhone/i) != null ||
            win.navigator.userAgent.match(/iPad/i) != null);
    }
    static getUrlObject(uriString) {
        // All the methods below require a protocol to properly parse a URL string
        // Assume http if no other protocol is present
        const hasProtocol = uriString.indexOf("://") > -1;
        if (!hasProtocol && uriString.indexOf(".") > -1) {
            uriString = "http://" + uriString;
        }
        else if (!hasProtocol) {
            return null;
        }
        try {
            if (nodeURL != null) {
                return new nodeURL.URL(uriString);
            }
            return new URL(uriString);
            // FIXME: Remove when updating file. Eslint update
            // eslint-disable-next-line @typescript-eslint/no-unused-vars
        }
        catch (e) {
            // Ignore error
        }
        return null;
    }
}
utils_Utils.inited = false;
utils_Utils.isNode = false;
utils_Utils.isBrowser = true;
utils_Utils.isMobileBrowser = false;
utils_Utils.isAppleMobileBrowser = false;
utils_Utils.global = null;
// Transpiled version of /\p{Emoji_Presentation}/gu using https://mothereff.in/regexpu. Used for compatability in older browsers.
utils_Utils.regexpEmojiPresentation = /(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])/g;
utils_Utils.validHosts = ["localhost"];
utils_Utils.originalMinimumPasswordLength = 8;
utils_Utils.minimumPasswordLength = 12;
utils_Utils.maximumPasswordLength = 128;
utils_Utils.DomainMatchBlacklist = new Map([
    ["google.com", new Set(["script.google.com"])],
]);
/** @deprecated Use guidRegex from @bitwarden/guid instead */
utils_Utils.guidRegex = /^[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/;
utils_Utils.init();

;// ../../libs/serialization/src/deserialization-helpers.ts
/**
 *
 * @param elementDeserializer
 * @returns
 */
function array(elementDeserializer) {
    return (array) => {
        if (array == null) {
            return null;
        }
        return array.map((element) => elementDeserializer(element));
    };
}
/**
 *
 * @param valueDeserializer
 */
function record(valueDeserializer) {
    return (jsonValue) => {
        if (jsonValue == null) {
            return null;
        }
        const output = {};
        Object.entries(jsonValue).forEach(([key, value]) => {
            output[key] = valueDeserializer(value);
        });
        return output;
    };
}

;// ../../libs/state/src/core/key-definition.ts

/**
 * KeyDefinitions describe the precise location to store data for a given piece of state.
 * The StateDefinition is used to describe the domain of the state, and the KeyDefinition
 * sub-divides that domain into specific keys.
 */
class KeyDefinition {
    /**
     * Creates a new instance of a KeyDefinition
     * @param stateDefinition The state definition for which this key belongs to.
     * @param key The name of the key, this should be unique per domain.
     * @param options A set of options to customize the behavior of {@link KeyDefinition}. All options are required.
     * @param options.deserializer A function to use to safely convert your type from json to your expected type.
     *   Your data may be serialized/deserialized at any time and this needs callback needs to be able to faithfully re-initialize
     *   from the JSON object representation of your type.
     */
    constructor(stateDefinition, key, options) {
        var _a;
        this.stateDefinition = stateDefinition;
        this.key = key;
        this.options = options;
        if (options.deserializer == null) {
            throw new Error(`'deserializer' is a required property on key ${this.errorKeyName}`);
        }
        if (options.cleanupDelayMs < 0) {
            throw new Error(`'cleanupDelayMs' must be greater than or equal to 0. Value of ${options.cleanupDelayMs} passed to key ${this.errorKeyName} `);
        }
        // Normalize optional debug options
        const { enableUpdateLogging = false, enableRetrievalLogging = false } = (_a = options.debug) !== null && _a !== void 0 ? _a : {};
        this.debug = {
            enableUpdateLogging,
            enableRetrievalLogging,
        };
    }
    /**
     * Gets the deserializer configured for this {@link KeyDefinition}
     */
    get deserializer() {
        return this.options.deserializer;
    }
    /**
     * Gets the number of milliseconds to wait before cleaning up the state after the last subscriber has unsubscribed.
     */
    get cleanupDelayMs() {
        var _a;
        return this.options.cleanupDelayMs < 0 ? 0 : ((_a = this.options.cleanupDelayMs) !== null && _a !== void 0 ? _a : 1000);
    }
    /**
     * Creates a {@link KeyDefinition} for state that is an array.
     * @param stateDefinition The state definition to be added to the KeyDefinition
     * @param key The key to be added to the KeyDefinition
     * @param options The options to customize the final {@link KeyDefinition}.
     * @returns A {@link KeyDefinition} initialized for arrays, the options run
     * the deserializer on the provided options for each element of an array.
     *
     * @example
     * ```typescript
     * const MY_KEY = KeyDefinition.array<MyArrayElement>(MY_STATE, "key", {
     *   deserializer: (myJsonElement) => convertToElement(myJsonElement),
     * });
     * ```
     */
    static array(stateDefinition, key, 
    // We have them provide options for the element of the array, depending on future options we add, this could get a little weird.
    options) {
        return new KeyDefinition(stateDefinition, key, Object.assign(Object.assign({}, options), { deserializer: array((e) => options.deserializer(e)) }));
    }
    /**
     * Creates a {@link KeyDefinition} for state that is a record.
     * @param stateDefinition The state definition to be added to the KeyDefinition
     * @param key The key to be added to the KeyDefinition
     * @param options The options to customize the final {@link KeyDefinition}.
     * @returns A {@link KeyDefinition} that contains a serializer that will run the provided deserializer for each
     * value in a record and returns every key as a string.
     *
     * @example
     * ```typescript
     * const MY_KEY = KeyDefinition.record<MyRecordValue>(MY_STATE, "key", {
     *   deserializer: (myJsonValue) => convertToValue(myJsonValue),
     * });
     * ```
     */
    static record(stateDefinition, key, 
    // We have them provide options for the value of the record, depending on future options we add, this could get a little weird.
    options) {
        return new KeyDefinition(stateDefinition, key, Object.assign(Object.assign({}, options), { deserializer: record((v) => options.deserializer(v)) }));
    }
    get fullName() {
        return `${this.stateDefinition.name}_${this.key}`;
    }
    get errorKeyName() {
        return `${this.stateDefinition.name} > ${this.key}`;
    }
}

;// ../../libs/guid/src/index.ts
const guidRegex = /^[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i;
function newGuid() {
    return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
        const r = (Math.random() * 16) | 0;
        const v = c === "x" ? r : (r & 0x3) | 0x8;
        return v.toString(16);
    });
}
function src_isGuid(id) {
    return guidRegex.test(id);
}

;// ../../libs/state/src/core/user-key-definition.ts
var _a;
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


const USER_KEY_DEFINITION_MARKER = Symbol("UserKeyDefinition");
class UserKeyDefinition {
    constructor(stateDefinition, key, options) {
        var _b;
        this.stateDefinition = stateDefinition;
        this.key = key;
        this.options = options;
        this[_a] = true;
        if (options.deserializer == null) {
            throw new Error(`'deserializer' is a required property on key ${this.errorKeyName}`);
        }
        if (options.cleanupDelayMs < 0) {
            throw new Error(`'cleanupDelayMs' must be greater than or equal to 0. Value of ${options.cleanupDelayMs} passed to key ${this.errorKeyName} `);
        }
        // Filter out repeat values
        this.clearOn = Array.from(new Set(options.clearOn));
        // Normalize optional debug options
        const { enableUpdateLogging = false, enableRetrievalLogging = false } = (_b = options.debug) !== null && _b !== void 0 ? _b : {};
        this.debug = {
            enableUpdateLogging,
            enableRetrievalLogging,
        };
    }
    /**
     * Gets the deserializer configured for this {@link KeyDefinition}
     */
    get deserializer() {
        return this.options.deserializer;
    }
    /**
     * Gets the number of milliseconds to wait before cleaning up the state after the last subscriber has unsubscribed.
     */
    get cleanupDelayMs() {
        var _b;
        return this.options.cleanupDelayMs < 0 ? 0 : ((_b = this.options.cleanupDelayMs) !== null && _b !== void 0 ? _b : 1000);
    }
    /**
     * Creates a {@link UserKeyDefinition} for state that is an array.
     * @param stateDefinition The state definition to be added to the UserKeyDefinition
     * @param key The key to be added to the KeyDefinition
     * @param options The options to customize the final {@link UserKeyDefinition}.
     * @returns A {@link UserKeyDefinition} initialized for arrays, the options run
     * the deserializer on the provided options for each element of an array
     * **unless that array is null, in which case it will return an empty list.**
     *
     * @example
     * ```typescript
     * const MY_KEY = UserKeyDefinition.array<MyArrayElement>(MY_STATE, "key", {
     *   deserializer: (myJsonElement) => convertToElement(myJsonElement),
     * });
     * ```
     */
    static array(stateDefinition, key, 
    // We have them provide options for the element of the array, depending on future options we add, this could get a little weird.
    options) {
        return new UserKeyDefinition(stateDefinition, key, Object.assign(Object.assign({}, options), { deserializer: array((e) => options.deserializer(e)) }));
    }
    /**
     * Creates a {@link UserKeyDefinition} for state that is a record.
     * @param stateDefinition The state definition to be added to the UserKeyDefinition
     * @param key The key to be added to the KeyDefinition
     * @param options The options to customize the final {@link UserKeyDefinition}.
     * @returns A {@link UserKeyDefinition} that contains a serializer that will run the provided deserializer for each
     * value in a record and returns every key as a string **unless that record is null, in which case it will return an record.**
     *
     * @example
     * ```typescript
     * const MY_KEY = UserKeyDefinition.record<MyRecordValue>(MY_STATE, "key", {
     *   deserializer: (myJsonValue) => convertToValue(myJsonValue),
     * });
     * ```
     */
    static record(stateDefinition, key, 
    // We have them provide options for the value of the record, depending on future options we add, this could get a little weird.
    options) {
        return new UserKeyDefinition(stateDefinition, key, Object.assign(Object.assign({}, options), { deserializer: record((v) => options.deserializer(v)) }));
    }
    get fullName() {
        return `${this.stateDefinition.name}_${this.key}`;
    }
    buildKey(userId) {
        if (!src_isGuid(userId)) {
            throw new Error(`You cannot build a user key without a valid UserId, building for key ${this.fullName}`);
        }
        return `user_${userId}_${this.stateDefinition.name}_${this.key}`;
    }
    get errorKeyName() {
        return `${this.stateDefinition.name} > ${this.key}`;
    }
}
_a = USER_KEY_DEFINITION_MARKER;

;// ../../libs/state/src/core/user-state.ts
const activeMarker = Symbol("active");

;// ../../libs/state/src/core/state-definition.ts
/**
 * Defines the base location and instruction of where this state is expected to be located.
 */
class StateDefinition {
    /**
     * Creates a new instance of {@link StateDefinition}, the creation of which is owned by the platform team.
     * @param name The name of the state, this needs to be unique from all other {@link StateDefinition}'s.
     * @param defaultStorageLocation The location of where this state should be stored.
     */
    constructor(name, defaultStorageLocation, storageLocationOverrides) {
        this.name = name;
        this.defaultStorageLocation = defaultStorageLocation;
        this.storageLocationOverrides = storageLocationOverrides !== null && storageLocationOverrides !== void 0 ? storageLocationOverrides : {};
    }
}

;// ../../libs/state/src/core/state-definitions.ts

/**
 * `StateDefinition`s comes with some rules, to facilitate a quick review from
 * platform of this file, ensure you follow these rules, the ones marked with (tested)
 * have unit tests that you can run locally.
 *
 * 1. (tested) Names should not be null or undefined
 * 2. (tested) Name and storage location should be unique
 * 3. (tested) Name and storage location can't differ from another export by only casing
 * 4. (tested) Name should be longer than 3 characters. It should be descriptive, but brief.
 * 5. (tested) Name should not contain spaces or underscores
 * 6. Name should be human readable
 * 7. Name should be in camelCase format (unit tests ensure the first character is lowercase)
 * 8. Teams should only use state definitions they have created
 * 9. StateDefinitions should only be used for keys relating to the state name they chose
 *
 */
// Admin Console
const ORGANIZATIONS_DISK = new StateDefinition("organizations", "disk");
const POLICIES_DISK = new StateDefinition("policies", "disk");
const PROVIDERS_DISK = new StateDefinition("providers", "disk");
const ORGANIZATION_MANAGEMENT_PREFERENCES_DISK = new StateDefinition("organizationManagementPreferences", "disk", {
    web: "disk-local",
});
const DELETE_MANAGED_USER_WARNING = new StateDefinition("showDeleteManagedUserWarning", "disk", {
    web: "disk-local",
});
const AUTO_CONFIRM = new StateDefinition("autoConfirm", "disk", { web: "disk-local" });
// Billing
const BILLING_DISK = new StateDefinition("billing", "disk");
const BILLING_MEMORY = new StateDefinition("billing", "memory");
// Auth
const ACCOUNT_DISK = new StateDefinition("account", "disk");
const ACCOUNT_MEMORY = new StateDefinition("account", "memory");
const AUTH_REQUEST_DISK_LOCAL = new StateDefinition("authRequestLocal", "disk", {
    web: "disk-local",
});
const AVATAR_DISK = new StateDefinition("avatar", "disk", { web: "disk-local" });
const DEVICE_TRUST_DISK_LOCAL = new StateDefinition("deviceTrust", "disk", {
    web: "disk-local",
    browser: "disk-backup-local-storage",
});
const LOGIN_EMAIL_DISK = new StateDefinition("loginEmail", "disk", {
    web: "disk-local",
});
const LOGIN_EMAIL_MEMORY = new StateDefinition("loginEmail", "memory");
const LOGIN_STRATEGY_MEMORY = new StateDefinition("loginStrategy", "memory");
const MASTER_PASSWORD_DISK = new StateDefinition("masterPassword", "disk");
const MASTER_PASSWORD_MEMORY = new StateDefinition("masterPassword", "memory");
const MASTER_PASSWORD_UNLOCK_DISK = new StateDefinition("masterPasswordUnlock", "disk");
const ROUTER_DISK = new StateDefinition("router", "disk");
const SSO_DISK = new StateDefinition("ssoLogin", "disk");
const SSO_DISK_LOCAL = new StateDefinition("ssoLoginLocal", "disk", { web: "disk-local" });
const TOKEN_DISK = new StateDefinition("token", "disk");
const TOKEN_DISK_LOCAL = new StateDefinition("tokenDiskLocal", "disk", {
    web: "disk-local",
});
const TOKEN_MEMORY = new StateDefinition("token", "memory");
const SEND_ACCESS_DISK = new StateDefinition("sendAccess", "disk");
const TWO_FACTOR_MEMORY = new StateDefinition("twoFactor", "memory");
const USER_DECRYPTION_OPTIONS_DISK = new StateDefinition("userDecryptionOptions", "disk");
const ORGANIZATION_INVITE_DISK = new StateDefinition("organizationInvite", "disk");
const VAULT_TIMEOUT_SETTINGS_DISK_LOCAL = new StateDefinition("vaultTimeoutSettings", "disk", {
    web: "disk-local",
});
const VAULT_TIMEOUT_SETTINGS_MEMORY = new StateDefinition("vaultTimeoutSettings", "memory");
// Autofill
const BADGE_SETTINGS_DISK = new StateDefinition("badgeSettings", "disk");
const USER_NOTIFICATION_SETTINGS_DISK = new StateDefinition("userNotificationSettings", "disk");
const DOMAIN_SETTINGS_DISK = new StateDefinition("domainSettings", "disk");
const AUTOFILL_SETTINGS_DISK = new StateDefinition("autofillSettings", "disk");
const AUTOFILL_SETTINGS_DISK_LOCAL = new StateDefinition("autofillSettingsLocal", "disk", {
    web: "disk-local",
});
const AUTOTYPE_SETTINGS_DISK = new StateDefinition("autotypeSettings", "disk");
// Components
const NEW_WEB_LAYOUT_BANNER_DISK = new StateDefinition("newWebLayoutBanner", "disk", {
    web: "disk-local",
});
const BIT_SIDE_NAV_DISK = new StateDefinition("bitSideNav", "disk");
// DIRT
const PHISHING_DETECTION_DISK = new StateDefinition("phishingDetection", "disk");
// Platform
const APPLICATION_ID_DISK = new StateDefinition("applicationId", "disk", {
    web: "disk-local",
});
const CLEAR_EVENT_DISK = new StateDefinition("clearEvent", "disk");
const CONFIG_DISK = new StateDefinition("config", "disk", {
    web: "disk-local",
});
const DESKTOP_SETTINGS_DISK = new StateDefinition("desktopSettings", "disk");
const ENVIRONMENT_DISK = new StateDefinition("environment", "disk");
const ENVIRONMENT_MEMORY = new StateDefinition("environment", "memory");
const IPC_MEMORY = new StateDefinition("interProcessCommunication", "memory");
const POPUP_VIEW_MEMORY = new StateDefinition("popupView", "memory", {
    browser: "memory-large-object",
});
const SYNC_DISK = new StateDefinition("sync", "disk", { web: "memory" });
const THEMING_DISK = new StateDefinition("theming", "disk", { web: "disk-local" });
const TRANSLATION_DISK = new StateDefinition("translation", "disk", { web: "disk-local" });
const ANIMATION_DISK = new StateDefinition("animation", "disk");
const TASK_SCHEDULER_DISK = new StateDefinition("taskScheduler", "disk");
const EXTENSION_INITIAL_INSTALL_DISK = new StateDefinition("extensionInitialInstall", "disk");
const WEB_PUSH_SUBSCRIPTION = new StateDefinition("webPushSubscription", "disk", {
    web: "disk-local",
});
const SERVER_COMMUNICATION_CONFIG_DISK = new StateDefinition("serverCommunicationConfig", "disk");
// Design System
const POPUP_STYLE_DISK = new StateDefinition("popupStyle", "disk");
// Secrets Manager
const SM_ONBOARDING_DISK = new StateDefinition("smOnboarding", "disk", {
    web: "disk-local",
});
// Tools
const EXTENSION_DISK = new StateDefinition("extension", "disk");
const GENERATOR_DISK = new StateDefinition("generator", "disk");
const GENERATOR_MEMORY = new StateDefinition("generator", "memory");
const BROWSER_SEND_MEMORY = new StateDefinition("sendBrowser", "memory");
const EVENT_COLLECTION_DISK = new StateDefinition("eventCollection", "disk");
const SEND_DISK = new StateDefinition("encryptedSend", "disk", {
    web: "memory",
});
const SEND_MEMORY = new StateDefinition("decryptedSend", "memory", {
    browser: "memory-large-object",
});
const SEND_ACCESS_AUTH_MEMORY = new StateDefinition("sendAccessAuth", "memory");
// Vault
const COLLECTION_DISK = new StateDefinition("collection", "disk", {
    web: "memory",
});
const COLLECTION_MEMORY = new StateDefinition("decryptedCollections", "memory", {
    browser: "memory-large-object",
});
const FOLDER_DISK = new StateDefinition("folder", "disk", { web: "memory" });
const FOLDER_MEMORY = new StateDefinition("decryptedFolders", "memory", {
    browser: "memory-large-object",
});
const VAULT_FILTER_DISK = new StateDefinition("vaultFilter", "disk", {
    web: "disk-local",
});
const VAULT_ONBOARDING = new StateDefinition("vaultOnboarding", "disk", {
    web: "disk-local",
});
const VAULT_SETTINGS_DISK = new StateDefinition("vaultSettings", "disk", {
    web: "disk-local",
});
const VAULT_BROWSER_MEMORY = new StateDefinition("vaultBrowser", "memory", {
    browser: "memory-large-object",
});
const VAULT_SEARCH_MEMORY = new StateDefinition("vaultSearch", "memory", {
    browser: "memory-large-object",
});
const CIPHERS_DISK = new StateDefinition("ciphers", "disk", { web: "memory" });
const CIPHERS_DISK_LOCAL = new StateDefinition("ciphersLocal", "disk", {
    web: "disk-local",
});
const CIPHERS_MEMORY = new StateDefinition("ciphersMemory", "memory", {
    browser: "memory-large-object",
});
const BANNERS_DISMISSED_DISK = new StateDefinition("bannersDismissed", "disk");
const VAULT_APPEARANCE = new StateDefinition("vaultAppearance", "disk");
const SECURITY_TASKS_DISK = new StateDefinition("securityTasks", "disk");
const AT_RISK_PASSWORDS_PAGE_DISK = new StateDefinition("atRiskPasswordsPage", "disk");
const NOTIFICATION_DISK = new StateDefinition("notifications", "disk");
const NUDGES_DISK = new StateDefinition("nudges", "disk", { web: "disk-local" });
const SETUP_EXTENSION_DISMISSED_DISK = new StateDefinition("setupExtensionDismissed", "disk", {
    web: "disk-local",
});
const VAULT_WELCOME_DIALOG_DISK = new StateDefinition("vaultWelcomeDialog", "disk", {
    web: "disk-local",
});
const VAULT_BROWSER_INTRO_CAROUSEL = new StateDefinition("vaultBrowserIntroCarousel", "disk");
const VAULT_AUTOFILL_SIMPLIFIED_ICON = new StateDefinition("vaultAutofillSimplifiedIcon", "disk");
const VAULT_AT_RISK_PASSWORDS_MEMORY = new StateDefinition("vaultAtRiskPasswords", "memory");
const WELCOME_EXTENSION_DIALOG_DISK = new StateDefinition("vaultWelcomeExtensionDialogDismissed", "disk", {
    web: "disk-local",
});
// KM
const BIOMETRIC_SETTINGS_DISK = new StateDefinition("biometricSettings", "disk");
const ENCRYPTED_MIGRATION_DISK = new StateDefinition("encryptedMigration", "disk");
const PIN_DISK = new StateDefinition("pinUnlock", "disk");
const PIN_MEMORY = new StateDefinition("pinUnlock", "memory");
const CRYPTO_DISK = new StateDefinition("crypto", "disk");
const CRYPTO_MEMORY = new StateDefinition("crypto", "memory");
const KDF_CONFIG_DISK = new StateDefinition("kdfConfig", "disk");
const KEY_CONNECTOR_DISK = new StateDefinition("keyConnector", "disk");

;// ../../libs/state/src/core/index.ts













;// ../../libs/state/src/state-migrations/migration-builder.ts
var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
class MigrationBuilder {
    /** Create a new MigrationBuilder with an empty buffer of migrations to perform.
     *
     * Add migrations to the buffer with {@link with} and {@link rollback}.
     * @returns A new MigrationBuilder.
     */
    static create() {
        return new MigrationBuilder([]);
    }
    constructor(migrations) {
        this.migrations = migrations;
    }
    /** Add a migrator to the MigrationBuilder. Types are updated such that the chained MigrationBuilder must currently be
     * at state version equal to the from version of the migrator. Return as MigrationBuilder<TTo> where TTo is the to
     * version of the migrator, so that the next migrator can be chained.
     *
     * @param migrate A migrator class or a tuple of a migrator class, the from version, and the to version. A tuple is
     * required to instantiate version numbers unless a default constructor is defined.
     * @returns A new MigrationBuilder with the to version of the migrator as the current version.
     */
    with(...migrate) {
        return this.addMigrator(migrate, "up");
    }
    /** Add a migrator to rollback on the MigrationBuilder's list of migrations. As with {@link with}, types of
     * MigrationBuilder and Migrator must align. However, this time the migration is reversed so TCurrent of the
     * MigrationBuilder must be equal to the to version of the migrator. Return as MigrationBuilder<TFrom> where TFrom
     * is the from version of the migrator, so that the next migrator can be chained.
     *
     * @param migrate A migrator class or a tuple of a migrator class, the from version, and the to version. A tuple is
     * required to instantiate version numbers unless a default constructor is defined.
     * @returns A new MigrationBuilder with the from version of the migrator as the current version.
     */
    rollback(...migrate) {
        if (migrate.length === 3) {
            migrate = [migrate[0], migrate[2], migrate[1]];
        }
        return this.addMigrator(migrate, "down");
    }
    /** Execute the migrations as defined in the MigrationBuilder's migrator buffer */
    migrate(helper) {
        return this.migrations.reduce((promise, migrator) => promise.then(() => __awaiter(this, void 0, void 0, function* () {
            yield this.runMigrator(migrator.migrator, helper, migrator.direction);
        })), Promise.resolve());
    }
    addMigrator(migrate, direction = "up") {
        const newMigration = migrate.length === 1
            ? { migrator: new migrate[0](), direction }
            : { migrator: new migrate[0](migrate[1], migrate[2]), direction };
        return new MigrationBuilder([...this.migrations, newMigration]);
    }
    runMigrator(migrator, helper, direction) {
        return __awaiter(this, void 0, void 0, function* () {
            const shouldMigrate = yield migrator.shouldMigrate(helper, direction);
            helper.info(`Migrator ${migrator.constructor.name} (to version ${migrator.toVersion}) should migrate: ${shouldMigrate} - ${direction}`);
            if (shouldMigrate) {
                const method = direction === "up" ? migrator.migrate : migrator.rollback;
                yield method.bind(migrator)(helper);
                helper.info(`Migrator ${migrator.constructor.name} (to version ${migrator.toVersion}) migrated - ${direction}`);
                yield migrator.updateVersion(helper, direction);
                helper.info(`Migrator ${migrator.constructor.name} (to version ${migrator.toVersion}) updated version - ${direction}`);
            }
        });
    }
}

;// ../../libs/state/src/state-migrations/migrator.ts
var migrator_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
const IRREVERSIBLE = new Error("Irreversible migration");
class Migrator {
    constructor(fromVersion, toVersion) {
        this.fromVersion = fromVersion;
        this.toVersion = toVersion;
        if (fromVersion == null || toVersion == null) {
            throw new Error("Invalid migration");
        }
        if (fromVersion > toVersion) {
            throw new Error("Invalid migration");
        }
    }
    shouldMigrate(helper, direction) {
        const startVersion = direction === "up" ? this.fromVersion : this.toVersion;
        return Promise.resolve(helper.currentVersion === startVersion);
    }
    updateVersion(helper, direction) {
        return migrator_awaiter(this, void 0, void 0, function* () {
            const endVersion = direction === "up" ? this.toVersion : this.fromVersion;
            helper.currentVersion = endVersion;
            yield helper.set("stateVersion", endVersion);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/10-move-ever-had-user-key-to-state-providers.ts
var _10_move_ever_had_user_key_to_state_providers_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const USER_EVER_HAD_USER_KEY = {
    key: "everHadUserKey",
    stateDefinition: {
        name: "crypto",
    },
};
class EverHadUserKeyMigrator extends Migrator {
    migrate(helper) {
        return _10_move_ever_had_user_key_to_state_providers_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _10_move_ever_had_user_key_to_state_providers_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const value = (_a = account === null || account === void 0 ? void 0 : account.profile) === null || _a === void 0 ? void 0 : _a.everHadUserKey;
                    yield helper.setToUser(userId, USER_EVER_HAD_USER_KEY, value !== null && value !== void 0 ? value : false);
                    if (value != null) {
                        delete account.profile.everHadUserKey;
                    }
                    yield helper.set(userId, account);
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
    rollback(helper) {
        return _10_move_ever_had_user_key_to_state_providers_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function rollbackAccount(userId, account) {
                return _10_move_ever_had_user_key_to_state_providers_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const value = yield helper.getFromUser(userId, USER_EVER_HAD_USER_KEY);
                    if (account) {
                        account.profile = Object.assign((_a = account.profile) !== null && _a !== void 0 ? _a : {}, {
                            everHadUserKey: value,
                        });
                        yield helper.set(userId, account);
                    }
                    yield helper.setToUser(userId, USER_EVER_HAD_USER_KEY, null);
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/11-move-org-keys-to-state-providers.ts
var _11_move_org_keys_to_state_providers_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const USER_ENCRYPTED_ORGANIZATION_KEYS = {
    key: "organizationKeys",
    stateDefinition: {
        name: "crypto",
    },
};
class OrganizationKeyMigrator extends Migrator {
    migrate(helper) {
        return _11_move_org_keys_to_state_providers_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _11_move_org_keys_to_state_providers_awaiter(this, void 0, void 0, function* () {
                    var _a, _b;
                    const value = (_b = (_a = account === null || account === void 0 ? void 0 : account.keys) === null || _a === void 0 ? void 0 : _a.organizationKeys) === null || _b === void 0 ? void 0 : _b.encrypted;
                    if (value != null) {
                        yield helper.setToUser(userId, USER_ENCRYPTED_ORGANIZATION_KEYS, value);
                        delete account.keys.organizationKeys;
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
    rollback(helper) {
        return _11_move_org_keys_to_state_providers_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function rollbackAccount(userId, account) {
                return _11_move_org_keys_to_state_providers_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const value = yield helper.getFromUser(userId, USER_ENCRYPTED_ORGANIZATION_KEYS);
                    if (account && value) {
                        account.keys = Object.assign((_a = account.keys) !== null && _a !== void 0 ? _a : {}, {
                            organizationKeys: {
                                encrypted: value,
                            },
                        });
                        yield helper.set(userId, account);
                    }
                    yield helper.setToUser(userId, USER_ENCRYPTED_ORGANIZATION_KEYS, null);
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/12-move-environment-state-to-providers.ts
var _12_move_environment_state_to_providers_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const ENVIRONMENT_STATE = { name: "environment" };
const REGION_KEY = { key: "region", stateDefinition: ENVIRONMENT_STATE };
const URLS_KEY = { key: "urls", stateDefinition: ENVIRONMENT_STATE };
class MoveEnvironmentStateToProviders extends Migrator {
    migrate(helper) {
        return _12_move_environment_state_to_providers_awaiter(this, void 0, void 0, function* () {
            const legacyGlobal = yield helper.get("global");
            // Move global data
            if ((legacyGlobal === null || legacyGlobal === void 0 ? void 0 : legacyGlobal.region) != null) {
                yield helper.setToGlobal(REGION_KEY, legacyGlobal.region);
            }
            if ((legacyGlobal === null || legacyGlobal === void 0 ? void 0 : legacyGlobal.environmentUrls) != null) {
                yield helper.setToGlobal(URLS_KEY, legacyGlobal.environmentUrls);
            }
            const legacyAccounts = yield helper.getAccounts();
            yield Promise.all(legacyAccounts.map((_a) => _12_move_environment_state_to_providers_awaiter(this, [_a], void 0, function* ({ userId, account }) {
                var _b, _c, _d, _e;
                // Move account data
                if (((_b = account === null || account === void 0 ? void 0 : account.settings) === null || _b === void 0 ? void 0 : _b.region) != null) {
                    yield helper.setToUser(userId, REGION_KEY, account.settings.region);
                }
                if (((_c = account === null || account === void 0 ? void 0 : account.settings) === null || _c === void 0 ? void 0 : _c.environmentUrls) != null) {
                    yield helper.setToUser(userId, URLS_KEY, account.settings.environmentUrls);
                }
                // Delete old account data
                (_d = account === null || account === void 0 ? void 0 : account.settings) === null || _d === void 0 ? true : delete _d.region;
                (_e = account === null || account === void 0 ? void 0 : account.settings) === null || _e === void 0 ? true : delete _e.environmentUrls;
                yield helper.set(userId, account);
            })));
            // Delete legacy global data
            legacyGlobal === null || legacyGlobal === void 0 ? true : delete legacyGlobal.region;
            legacyGlobal === null || legacyGlobal === void 0 ? true : delete legacyGlobal.environmentUrls;
            yield helper.set("global", legacyGlobal);
        });
    }
    rollback(helper) {
        return _12_move_environment_state_to_providers_awaiter(this, void 0, void 0, function* () {
            let legacyGlobal = yield helper.get("global");
            let updatedLegacyGlobal = false;
            const globalRegion = yield helper.getFromGlobal(REGION_KEY);
            if (globalRegion) {
                if (!legacyGlobal) {
                    legacyGlobal = {};
                }
                updatedLegacyGlobal = true;
                legacyGlobal.region = globalRegion;
                yield helper.setToGlobal(REGION_KEY, null);
            }
            const globalUrls = yield helper.getFromGlobal(URLS_KEY);
            if (globalUrls) {
                if (!legacyGlobal) {
                    legacyGlobal = {};
                }
                updatedLegacyGlobal = true;
                legacyGlobal.environmentUrls = globalUrls;
                yield helper.setToGlobal(URLS_KEY, null);
            }
            if (updatedLegacyGlobal) {
                yield helper.set("global", legacyGlobal);
            }
            function rollbackUser(userId, account) {
                return _12_move_environment_state_to_providers_awaiter(this, void 0, void 0, function* () {
                    let updatedAccount = false;
                    const userRegion = yield helper.getFromUser(userId, REGION_KEY);
                    if (userRegion) {
                        if (!account) {
                            account = {};
                        }
                        if (!account.settings) {
                            account.settings = {};
                        }
                        updatedAccount = true;
                        account.settings.region = userRegion;
                        yield helper.setToUser(userId, REGION_KEY, null);
                    }
                    const userUrls = yield helper.getFromUser(userId, URLS_KEY);
                    if (userUrls) {
                        if (!account) {
                            account = {};
                        }
                        if (!account.settings) {
                            account.settings = {};
                        }
                        updatedAccount = true;
                        account.settings.environmentUrls = userUrls;
                        yield helper.setToUser(userId, URLS_KEY, null);
                    }
                    if (updatedAccount) {
                        yield helper.set(userId, account);
                    }
                });
            }
            const accounts = yield helper.getAccounts();
            yield Promise.all(accounts.map(({ userId, account }) => rollbackUser(userId, account)));
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/13-move-provider-keys-to-state-providers.ts
var _13_move_provider_keys_to_state_providers_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const USER_ENCRYPTED_PROVIDER_KEYS = {
    key: "providerKeys",
    stateDefinition: {
        name: "crypto",
    },
};
class ProviderKeyMigrator extends Migrator {
    migrate(helper) {
        return _13_move_provider_keys_to_state_providers_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _13_move_provider_keys_to_state_providers_awaiter(this, void 0, void 0, function* () {
                    var _a, _b;
                    const value = (_b = (_a = account === null || account === void 0 ? void 0 : account.keys) === null || _a === void 0 ? void 0 : _a.providerKeys) === null || _b === void 0 ? void 0 : _b.encrypted;
                    if (value != null) {
                        yield helper.setToUser(userId, USER_ENCRYPTED_PROVIDER_KEYS, value);
                        delete account.keys.providerKeys;
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
    rollback(helper) {
        return _13_move_provider_keys_to_state_providers_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function rollbackAccount(userId, account) {
                return _13_move_provider_keys_to_state_providers_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const value = yield helper.getFromUser(userId, USER_ENCRYPTED_PROVIDER_KEYS);
                    if (account && value) {
                        account.keys = Object.assign((_a = account.keys) !== null && _a !== void 0 ? _a : {}, {
                            providerKeys: {
                                encrypted: value,
                            },
                        });
                        yield helper.set(userId, account);
                    }
                    yield helper.setToUser(userId, USER_ENCRYPTED_PROVIDER_KEYS, null);
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/14-move-biometric-client-key-half-state-to-providers.ts
var _14_move_biometric_client_key_half_state_to_providers_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

// Biometric text, no auto prompt text, fingerprint validated, and prompt cancelled are refreshed on every app start, so we don't need to migrate them
const CLIENT_KEY_HALF = {
    key: "clientKeyHalf",
    stateDefinition: { name: "biometricSettings" },
};
class MoveBiometricClientKeyHalfToStateProviders extends Migrator {
    migrate(helper) {
        return _14_move_biometric_client_key_half_state_to_providers_awaiter(this, void 0, void 0, function* () {
            const legacyAccounts = yield helper.getAccounts();
            yield Promise.all(legacyAccounts.map((_a) => _14_move_biometric_client_key_half_state_to_providers_awaiter(this, [_a], void 0, function* ({ userId, account }) {
                var _b, _c;
                // Move account data
                if (((_b = account === null || account === void 0 ? void 0 : account.keys) === null || _b === void 0 ? void 0 : _b.biometricEncryptionClientKeyHalf) != null) {
                    yield helper.setToUser(userId, CLIENT_KEY_HALF, account.keys.biometricEncryptionClientKeyHalf);
                    // Delete old account data
                    (_c = account === null || account === void 0 ? void 0 : account.keys) === null || _c === void 0 ? true : delete _c.biometricEncryptionClientKeyHalf;
                    yield helper.set(userId, account);
                }
            })));
        });
    }
    rollback(helper) {
        return _14_move_biometric_client_key_half_state_to_providers_awaiter(this, void 0, void 0, function* () {
            function rollbackUser(userId, account) {
                return _14_move_biometric_client_key_half_state_to_providers_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    let updatedAccount = false;
                    const userKeyHalf = yield helper.getFromUser(userId, CLIENT_KEY_HALF);
                    if (userKeyHalf) {
                        account !== null && account !== void 0 ? account : (account = {});
                        (_a = account.keys) !== null && _a !== void 0 ? _a : (account.keys = {});
                        updatedAccount = true;
                        account.keys.biometricEncryptionClientKeyHalf = userKeyHalf;
                        yield helper.setToUser(userId, CLIENT_KEY_HALF, null);
                    }
                    if (updatedAccount) {
                        yield helper.set(userId, account);
                    }
                });
            }
            const accounts = yield helper.getAccounts();
            yield Promise.all(accounts.map(({ userId, account }) => rollbackUser(userId, account)));
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/15-move-folder-state-to-state-provider.ts
var _15_move_folder_state_to_state_provider_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const USER_ENCRYPTED_FOLDERS = {
    key: "folders",
    stateDefinition: {
        name: "folder",
    },
};
class FolderMigrator extends Migrator {
    migrate(helper) {
        return _15_move_folder_state_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _15_move_folder_state_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    var _a, _b;
                    const value = (_b = (_a = account === null || account === void 0 ? void 0 : account.data) === null || _a === void 0 ? void 0 : _a.folders) === null || _b === void 0 ? void 0 : _b.encrypted;
                    if (value != null) {
                        yield helper.setToUser(userId, USER_ENCRYPTED_FOLDERS, value);
                        delete account.data.folders;
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
    rollback(helper) {
        return _15_move_folder_state_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function rollbackAccount(userId, account) {
                return _15_move_folder_state_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const value = yield helper.getFromUser(userId, USER_ENCRYPTED_FOLDERS);
                    if (account) {
                        account.data = Object.assign((_a = account.data) !== null && _a !== void 0 ? _a : {}, {
                            folders: {
                                encrypted: value,
                            },
                        });
                        yield helper.set(userId, account);
                    }
                    yield helper.setToUser(userId, USER_ENCRYPTED_FOLDERS, null);
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/16-move-last-sync-to-state-provider.ts
var _16_move_last_sync_to_state_provider_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const LAST_SYNC_KEY = {
    key: "lastSync",
    stateDefinition: {
        name: "sync",
    },
};
class LastSyncMigrator extends Migrator {
    migrate(helper) {
        return _16_move_last_sync_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _16_move_last_sync_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const value = (_a = account === null || account === void 0 ? void 0 : account.profile) === null || _a === void 0 ? void 0 : _a.lastSync;
                    yield helper.setToUser(userId, LAST_SYNC_KEY, value !== null && value !== void 0 ? value : null);
                    if (value != null) {
                        delete account.profile.lastSync;
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
    rollback(helper) {
        return _16_move_last_sync_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function rollbackAccount(userId, account) {
                return _16_move_last_sync_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const value = yield helper.getFromUser(userId, LAST_SYNC_KEY);
                    if (account) {
                        account.profile = Object.assign((_a = account.profile) !== null && _a !== void 0 ? _a : {}, {
                            lastSync: value,
                        });
                        yield helper.set(userId, account);
                    }
                    yield helper.setToUser(userId, LAST_SYNC_KEY, null);
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/17-move-enable-passkeys-to-state-providers.ts
var _17_move_enable_passkeys_to_state_providers_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const USER_ENABLE_PASSKEYS = {
    key: "enablePasskeys",
    stateDefinition: {
        name: "vaultSettings",
    },
};
class EnablePasskeysMigrator extends Migrator {
    migrate(helper) {
        return _17_move_enable_passkeys_to_state_providers_awaiter(this, void 0, void 0, function* () {
            const global = yield helper.get("global");
            if ((global === null || global === void 0 ? void 0 : global.enablePasskeys) != null) {
                yield helper.setToGlobal(USER_ENABLE_PASSKEYS, global.enablePasskeys);
                global === null || global === void 0 ? true : delete global.enablePasskeys;
                yield helper.set("global", global);
            }
        });
    }
    rollback(helper) {
        return _17_move_enable_passkeys_to_state_providers_awaiter(this, void 0, void 0, function* () {
            let global = yield helper.get("global");
            const globalEnablePasskeys = yield helper.getFromGlobal(USER_ENABLE_PASSKEYS);
            if (globalEnablePasskeys != null) {
                global = Object.assign(global !== null && global !== void 0 ? global : {}, { enablePasskeys: globalEnablePasskeys });
                yield helper.set("global", global);
                yield helper.setToGlobal(USER_ENABLE_PASSKEYS, undefined);
            }
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/18-move-autofill-settings-to-state-providers.ts
var _18_move_autofill_settings_to_state_providers_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

// FIXME: Remove when updating file. Eslint update
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const AutofillOverlayVisibility = {
    Off: 0,
    OnButtonClick: 1,
    OnFieldFocus: 2,
};
const autofillSettingsStateDefinition = {
    stateDefinition: {
        name: "autofillSettings",
    },
};
class AutofillSettingsKeyMigrator extends Migrator {
    migrate(helper) {
        return _18_move_autofill_settings_to_state_providers_awaiter(this, void 0, void 0, function* () {
            // global state (e.g. "autoFillOverlayVisibility -> inlineMenuVisibility")
            const globalState = yield helper.get("global");
            if ((globalState === null || globalState === void 0 ? void 0 : globalState.autoFillOverlayVisibility) != null) {
                yield helper.setToGlobal({
                    stateDefinition: {
                        name: "autofillSettingsLocal",
                    },
                    key: "inlineMenuVisibility",
                }, globalState.autoFillOverlayVisibility);
                // delete `autoFillOverlayVisibility` from state global
                delete globalState.autoFillOverlayVisibility;
                yield helper.set("global", globalState);
            }
            // account state (e.g. account settings -> state provider framework keys)
            const accounts = yield helper.getAccounts();
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
            // migrate account state
            function migrateAccount(userId, account) {
                return _18_move_autofill_settings_to_state_providers_awaiter(this, void 0, void 0, function* () {
                    let updateAccount = false;
                    const accountSettings = account === null || account === void 0 ? void 0 : account.settings;
                    if ((accountSettings === null || accountSettings === void 0 ? void 0 : accountSettings.autoFillOnPageLoadDefault) != null) {
                        yield helper.setToUser(userId, Object.assign(Object.assign({}, autofillSettingsStateDefinition), { key: "autofillOnPageLoadDefault" }), accountSettings.autoFillOnPageLoadDefault);
                        delete account.settings.autoFillOnPageLoadDefault;
                        updateAccount = true;
                    }
                    if ((accountSettings === null || accountSettings === void 0 ? void 0 : accountSettings.enableAutoFillOnPageLoad) != null) {
                        yield helper.setToUser(userId, Object.assign(Object.assign({}, autofillSettingsStateDefinition), { key: "autofillOnPageLoad" }), accountSettings === null || accountSettings === void 0 ? void 0 : accountSettings.enableAutoFillOnPageLoad);
                        delete account.settings.enableAutoFillOnPageLoad;
                        updateAccount = true;
                    }
                    if ((accountSettings === null || accountSettings === void 0 ? void 0 : accountSettings.dismissedAutoFillOnPageLoadCallout) != null) {
                        yield helper.setToUser(userId, Object.assign(Object.assign({}, autofillSettingsStateDefinition), { key: "autofillOnPageLoadCalloutIsDismissed" }), accountSettings === null || accountSettings === void 0 ? void 0 : accountSettings.dismissedAutoFillOnPageLoadCallout);
                        delete account.settings.dismissedAutoFillOnPageLoadCallout;
                        updateAccount = true;
                    }
                    if ((accountSettings === null || accountSettings === void 0 ? void 0 : accountSettings.disableAutoTotpCopy) != null) {
                        yield helper.setToUser(userId, Object.assign(Object.assign({}, autofillSettingsStateDefinition), { key: "autoCopyTotp" }), 
                        // invert the value to match the new naming convention
                        !(accountSettings === null || accountSettings === void 0 ? void 0 : accountSettings.disableAutoTotpCopy));
                        delete account.settings.disableAutoTotpCopy;
                        updateAccount = true;
                    }
                    if ((accountSettings === null || accountSettings === void 0 ? void 0 : accountSettings.activateAutoFillOnPageLoadFromPolicy) != null) {
                        yield helper.setToUser(userId, {
                            stateDefinition: {
                                name: "autofillSettingsLocal",
                            },
                            key: "activateAutofillOnPageLoadFromPolicy",
                        }, accountSettings === null || accountSettings === void 0 ? void 0 : accountSettings.activateAutoFillOnPageLoadFromPolicy);
                        delete account.settings.activateAutoFillOnPageLoadFromPolicy;
                        updateAccount = true;
                    }
                    if (updateAccount) {
                        // update the state account settings with the migrated values deleted
                        yield helper.set(userId, account);
                    }
                });
            }
        });
    }
    rollback(helper) {
        return _18_move_autofill_settings_to_state_providers_awaiter(this, void 0, void 0, function* () {
            // global state (e.g. "inlineMenuVisibility -> autoFillOverlayVisibility")
            const globalState = (yield helper.get("global")) || {};
            const inlineMenuVisibility = yield helper.getFromGlobal({
                stateDefinition: {
                    name: "autofillSettingsLocal",
                },
                key: "inlineMenuVisibility",
            });
            if (inlineMenuVisibility) {
                yield helper.set("global", Object.assign(Object.assign({}, globalState), { autoFillOverlayVisibility: inlineMenuVisibility }));
                // remove the global state provider framework key for `inlineMenuVisibility`
                yield helper.setToGlobal({
                    stateDefinition: {
                        name: "autofillSettingsLocal",
                    },
                    key: "inlineMenuVisibility",
                }, null);
            }
            // account state (e.g. state provider framework keys -> account settings)
            const accounts = yield helper.getAccounts();
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
            // rollback account state
            function rollbackAccount(userId, account) {
                return _18_move_autofill_settings_to_state_providers_awaiter(this, void 0, void 0, function* () {
                    let updateAccount = false;
                    let settings = (account === null || account === void 0 ? void 0 : account.settings) || {};
                    const autoFillOnPageLoadDefault = yield helper.getFromUser(userId, Object.assign(Object.assign({}, autofillSettingsStateDefinition), { key: "autofillOnPageLoadDefault" }));
                    const enableAutoFillOnPageLoad = yield helper.getFromUser(userId, Object.assign(Object.assign({}, autofillSettingsStateDefinition), { key: "autofillOnPageLoad" }));
                    const dismissedAutoFillOnPageLoadCallout = yield helper.getFromUser(userId, Object.assign(Object.assign({}, autofillSettingsStateDefinition), { key: "autofillOnPageLoadCalloutIsDismissed" }));
                    const autoCopyTotp = yield helper.getFromUser(userId, Object.assign(Object.assign({}, autofillSettingsStateDefinition), { key: "autoCopyTotp" }));
                    const activateAutoFillOnPageLoadFromPolicy = yield helper.getFromUser(userId, {
                        stateDefinition: {
                            name: "autofillSettingsLocal",
                        },
                        key: "activateAutofillOnPageLoadFromPolicy",
                    });
                    // update new settings and remove the account state provider framework keys for the rolled back values
                    if (autoFillOnPageLoadDefault != null) {
                        settings = Object.assign(Object.assign({}, settings), { autoFillOnPageLoadDefault });
                        yield helper.setToUser(userId, Object.assign(Object.assign({}, autofillSettingsStateDefinition), { key: "autofillOnPageLoadDefault" }), null);
                        updateAccount = true;
                    }
                    if (enableAutoFillOnPageLoad != null) {
                        settings = Object.assign(Object.assign({}, settings), { enableAutoFillOnPageLoad });
                        yield helper.setToUser(userId, Object.assign(Object.assign({}, autofillSettingsStateDefinition), { key: "autofillOnPageLoad" }), null);
                        updateAccount = true;
                    }
                    if (dismissedAutoFillOnPageLoadCallout != null) {
                        settings = Object.assign(Object.assign({}, settings), { dismissedAutoFillOnPageLoadCallout });
                        yield helper.setToUser(userId, Object.assign(Object.assign({}, autofillSettingsStateDefinition), { key: "autofillOnPageLoadCalloutIsDismissed" }), null);
                        updateAccount = true;
                    }
                    if (autoCopyTotp != null) {
                        // invert the value to match the new naming convention
                        settings = Object.assign(Object.assign({}, settings), { disableAutoTotpCopy: !autoCopyTotp });
                        yield helper.setToUser(userId, Object.assign(Object.assign({}, autofillSettingsStateDefinition), { key: "autoCopyTotp" }), null);
                        updateAccount = true;
                    }
                    if (activateAutoFillOnPageLoadFromPolicy != null) {
                        settings = Object.assign(Object.assign({}, settings), { activateAutoFillOnPageLoadFromPolicy });
                        yield helper.setToUser(userId, {
                            stateDefinition: {
                                name: "autofillSettingsLocal",
                            },
                            key: "activateAutofillOnPageLoadFromPolicy",
                        }, null);
                        updateAccount = true;
                    }
                    if (updateAccount) {
                        // commit updated settings to state
                        yield helper.set(userId, Object.assign(Object.assign({}, account), { settings }));
                    }
                });
            }
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/19-migrate-require-password-on-start.ts
var _19_migrate_require_password_on_start_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

// Biometric text, no auto prompt text, fingerprint validated, and prompt cancelled are refreshed on every app start, so we don't need to migrate them
const REQUIRE_PASSWORD_ON_START = {
    key: "requirePasswordOnStart",
    stateDefinition: { name: "biometricSettings" },
};
class RequirePasswordOnStartMigrator extends Migrator {
    migrate(helper) {
        return _19_migrate_require_password_on_start_awaiter(this, void 0, void 0, function* () {
            const legacyAccounts = yield helper.getAccounts();
            yield Promise.all(legacyAccounts.map((_a) => _19_migrate_require_password_on_start_awaiter(this, [_a], void 0, function* ({ userId, account }) {
                var _b;
                // Move account data
                if (((_b = account === null || account === void 0 ? void 0 : account.settings) === null || _b === void 0 ? void 0 : _b.requirePasswordOnStart) != null) {
                    yield helper.setToUser(userId, REQUIRE_PASSWORD_ON_START, account.settings.requirePasswordOnStart);
                    // Delete old account data
                    delete account.settings.requirePasswordOnStart;
                    yield helper.set(userId, account);
                }
            })));
        });
    }
    rollback(helper) {
        return _19_migrate_require_password_on_start_awaiter(this, void 0, void 0, function* () {
            function rollbackUser(userId, account) {
                return _19_migrate_require_password_on_start_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const requirePassword = yield helper.getFromUser(userId, REQUIRE_PASSWORD_ON_START);
                    if (requirePassword) {
                        account !== null && account !== void 0 ? account : (account = {});
                        (_a = account.settings) !== null && _a !== void 0 ? _a : (account.settings = {});
                        account.settings.requirePasswordOnStart = requirePassword;
                        yield helper.setToUser(userId, REQUIRE_PASSWORD_ON_START, null);
                        yield helper.set(userId, account);
                    }
                });
            }
            const accounts = yield helper.getAccounts();
            yield Promise.all(accounts.map(({ userId, account }) => rollbackUser(userId, account)));
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/20-move-private-key-to-state-providers.ts
var _20_move_private_key_to_state_providers_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const USER_ENCRYPTED_PRIVATE_KEY = {
    key: "privateKey",
    stateDefinition: {
        name: "crypto",
    },
};
class PrivateKeyMigrator extends Migrator {
    migrate(helper) {
        return _20_move_private_key_to_state_providers_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _20_move_private_key_to_state_providers_awaiter(this, void 0, void 0, function* () {
                    var _a, _b;
                    const value = (_b = (_a = account === null || account === void 0 ? void 0 : account.keys) === null || _a === void 0 ? void 0 : _a.privateKey) === null || _b === void 0 ? void 0 : _b.encrypted;
                    if (value != null) {
                        yield helper.setToUser(userId, USER_ENCRYPTED_PRIVATE_KEY, value);
                        delete account.keys.privateKey;
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
    rollback(helper) {
        return _20_move_private_key_to_state_providers_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function rollbackAccount(userId, account) {
                return _20_move_private_key_to_state_providers_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const value = yield helper.getFromUser(userId, USER_ENCRYPTED_PRIVATE_KEY);
                    if (account && value) {
                        account.keys = Object.assign((_a = account.keys) !== null && _a !== void 0 ? _a : {}, {
                            privateKey: {
                                encrypted: value,
                            },
                        });
                        yield helper.set(userId, account);
                    }
                    yield helper.setToUser(userId, USER_ENCRYPTED_PRIVATE_KEY, null);
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/21-move-collections-state-to-state-provider.ts
var _21_move_collections_state_to_state_provider_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const USER_ENCRYPTED_COLLECTIONS = {
    key: "collections",
    stateDefinition: {
        name: "collection",
    },
};
class CollectionMigrator extends Migrator {
    migrate(helper) {
        return _21_move_collections_state_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _21_move_collections_state_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    var _a, _b;
                    const value = (_b = (_a = account === null || account === void 0 ? void 0 : account.data) === null || _a === void 0 ? void 0 : _a.collections) === null || _b === void 0 ? void 0 : _b.encrypted;
                    if (value != null) {
                        yield helper.setToUser(userId, USER_ENCRYPTED_COLLECTIONS, value);
                        delete account.data.collections;
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
    rollback(helper) {
        return _21_move_collections_state_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function rollbackAccount(userId, account) {
                return _21_move_collections_state_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const value = yield helper.getFromUser(userId, USER_ENCRYPTED_COLLECTIONS);
                    if (account) {
                        account.data = Object.assign((_a = account.data) !== null && _a !== void 0 ? _a : {}, {
                            collections: {
                                encrypted: value,
                            },
                        });
                        yield helper.set(userId, account);
                    }
                    yield helper.setToUser(userId, USER_ENCRYPTED_COLLECTIONS, null);
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/22-move-collapsed-groupings-to-state-provider.ts
var _22_move_collapsed_groupings_to_state_provider_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const COLLAPSED_GROUPINGS = {
    key: "collapsedGroupings",
    stateDefinition: {
        name: "vaultFilter",
    },
};
class CollapsedGroupingsMigrator extends Migrator {
    migrate(helper) {
        return _22_move_collapsed_groupings_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _22_move_collapsed_groupings_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const value = (_a = account === null || account === void 0 ? void 0 : account.settings) === null || _a === void 0 ? void 0 : _a.collapsedGroupings;
                    if (value != null) {
                        yield helper.setToUser(userId, COLLAPSED_GROUPINGS, value);
                        delete account.settings.collapsedGroupings;
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
    rollback(helper) {
        return _22_move_collapsed_groupings_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function rollbackAccount(userId, account) {
                return _22_move_collapsed_groupings_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const value = yield helper.getFromUser(userId, COLLAPSED_GROUPINGS);
                    if (account) {
                        account.settings = Object.assign((_a = account.settings) !== null && _a !== void 0 ? _a : {}, {
                            collapsedGroupings: value,
                        });
                        yield helper.set(userId, account);
                    }
                    yield helper.setToUser(userId, COLLAPSED_GROUPINGS, null);
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/23-move-biometric-prompts-to-state-providers.ts
var _23_move_biometric_prompts_to_state_providers_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

// prompt cancelled is refreshed on every app start/quit/unlock, so we don't need to migrate it
const DISMISSED_BIOMETRIC_REQUIRE_PASSWORD_ON_START_CALLOUT = {
    key: "dismissedBiometricRequirePasswordOnStartCallout",
    stateDefinition: { name: "biometricSettings" },
};
const PROMPT_AUTOMATICALLY = {
    key: "promptAutomatically",
    stateDefinition: { name: "biometricSettings" },
};
class MoveBiometricPromptsToStateProviders extends Migrator {
    migrate(helper) {
        return _23_move_biometric_prompts_to_state_providers_awaiter(this, void 0, void 0, function* () {
            const legacyAccounts = yield helper.getAccounts();
            yield Promise.all(legacyAccounts.map((_a) => _23_move_biometric_prompts_to_state_providers_awaiter(this, [_a], void 0, function* ({ userId, account }) {
                var _b, _c, _d, _e;
                if (account == null) {
                    return;
                }
                // Move account data
                if (((_b = account === null || account === void 0 ? void 0 : account.settings) === null || _b === void 0 ? void 0 : _b.dismissedBiometricRequirePasswordOnStartCallout) != null) {
                    yield helper.setToUser(userId, DISMISSED_BIOMETRIC_REQUIRE_PASSWORD_ON_START_CALLOUT, account.settings.dismissedBiometricRequirePasswordOnStartCallout);
                }
                if (((_c = account === null || account === void 0 ? void 0 : account.settings) === null || _c === void 0 ? void 0 : _c.disableAutoBiometricsPrompt) != null) {
                    yield helper.setToUser(userId, PROMPT_AUTOMATICALLY, !account.settings.disableAutoBiometricsPrompt);
                }
                // Delete old account data
                (_d = account === null || account === void 0 ? void 0 : account.settings) === null || _d === void 0 ? true : delete _d.dismissedBiometricRequirePasswordOnStartCallout;
                (_e = account === null || account === void 0 ? void 0 : account.settings) === null || _e === void 0 ? true : delete _e.disableAutoBiometricsPrompt;
                yield helper.set(userId, account);
            })));
        });
    }
    rollback(helper) {
        return _23_move_biometric_prompts_to_state_providers_awaiter(this, void 0, void 0, function* () {
            function rollbackUser(userId, account) {
                return _23_move_biometric_prompts_to_state_providers_awaiter(this, void 0, void 0, function* () {
                    var _a, _b;
                    let updatedAccount = false;
                    const userDismissed = yield helper.getFromUser(userId, DISMISSED_BIOMETRIC_REQUIRE_PASSWORD_ON_START_CALLOUT);
                    if (userDismissed) {
                        account !== null && account !== void 0 ? account : (account = {});
                        (_a = account.settings) !== null && _a !== void 0 ? _a : (account.settings = {});
                        updatedAccount = true;
                        account.settings.dismissedBiometricRequirePasswordOnStartCallout = userDismissed;
                        yield helper.setToUser(userId, DISMISSED_BIOMETRIC_REQUIRE_PASSWORD_ON_START_CALLOUT, null);
                    }
                    const userPromptAutomatically = yield helper.getFromUser(userId, PROMPT_AUTOMATICALLY);
                    if (userPromptAutomatically != null) {
                        account !== null && account !== void 0 ? account : (account = {});
                        (_b = account.settings) !== null && _b !== void 0 ? _b : (account.settings = {});
                        updatedAccount = true;
                        account.settings.disableAutoBiometricsPrompt = !userPromptAutomatically;
                        yield helper.setToUser(userId, PROMPT_AUTOMATICALLY, null);
                    }
                    if (updatedAccount) {
                        yield helper.set(userId, account);
                    }
                });
            }
            const accounts = yield helper.getAccounts();
            yield Promise.all(accounts.map(({ userId, account }) => rollbackUser(userId, account)));
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/24-move-sm-onboarding-key-to-state-providers.ts
var _24_move_sm_onboarding_key_to_state_providers_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const SM_ONBOARDING_TASKS = {
    key: "tasks",
    stateDefinition: { name: "smOnboarding" },
};
class SmOnboardingTasksMigrator extends Migrator {
    migrate(helper) {
        return _24_move_sm_onboarding_key_to_state_providers_awaiter(this, void 0, void 0, function* () {
            const legacyAccounts = yield helper.getAccounts();
            yield Promise.all(legacyAccounts.map((_a) => _24_move_sm_onboarding_key_to_state_providers_awaiter(this, [_a], void 0, function* ({ userId, account }) {
                var _b;
                // Move account data
                if (((_b = account === null || account === void 0 ? void 0 : account.settings) === null || _b === void 0 ? void 0 : _b.smOnboardingTasks) != null) {
                    yield helper.setToUser(userId, SM_ONBOARDING_TASKS, account.settings.smOnboardingTasks);
                    // Delete old account data
                    delete account.settings.smOnboardingTasks;
                    yield helper.set(userId, account);
                }
            })));
        });
    }
    rollback(helper) {
        return _24_move_sm_onboarding_key_to_state_providers_awaiter(this, void 0, void 0, function* () {
            function rollbackUser(userId, account) {
                return _24_move_sm_onboarding_key_to_state_providers_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const smOnboardingTasks = yield helper.getFromUser(userId, SM_ONBOARDING_TASKS);
                    if (smOnboardingTasks) {
                        account !== null && account !== void 0 ? account : (account = {});
                        (_a = account.settings) !== null && _a !== void 0 ? _a : (account.settings = {});
                        account.settings.smOnboardingTasks = smOnboardingTasks;
                        yield helper.setToUser(userId, SM_ONBOARDING_TASKS, null);
                        yield helper.set(userId, account);
                    }
                });
            }
            const accounts = yield helper.getAccounts();
            yield Promise.all(accounts.map(({ userId, account }) => rollbackUser(userId, account)));
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/25-move-clear-clipboard-to-autofill-settings-state-provider.ts
var _25_move_clear_clipboard_to_autofill_settings_state_provider_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

// FIXME: Remove when updating file. Eslint update
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const ClearClipboardDelay = {
    Never: null,
    TenSeconds: 10,
    TwentySeconds: 20,
    ThirtySeconds: 30,
    OneMinute: 60,
    TwoMinutes: 120,
    FiveMinutes: 300,
};
const autofillSettingsLocalStateDefinition = {
    stateDefinition: {
        name: "autofillSettingsLocal",
    },
};
class ClearClipboardDelayMigrator extends Migrator {
    migrate(helper) {
        return _25_move_clear_clipboard_to_autofill_settings_state_provider_awaiter(this, void 0, void 0, function* () {
            // account state (e.g. account settings -> state provider framework keys)
            const accounts = yield helper.getAccounts();
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
            // migrate account state
            function migrateAccount(userId, account) {
                return _25_move_clear_clipboard_to_autofill_settings_state_provider_awaiter(this, void 0, void 0, function* () {
                    const accountSettings = account === null || account === void 0 ? void 0 : account.settings;
                    if ((accountSettings === null || accountSettings === void 0 ? void 0 : accountSettings.clearClipboard) !== undefined) {
                        yield helper.setToUser(userId, Object.assign(Object.assign({}, autofillSettingsLocalStateDefinition), { key: "clearClipboardDelay" }), accountSettings.clearClipboard);
                        delete account.settings.clearClipboard;
                        // update the state account settings with the migrated values deleted
                        yield helper.set(userId, account);
                    }
                });
            }
        });
    }
    rollback(helper) {
        return _25_move_clear_clipboard_to_autofill_settings_state_provider_awaiter(this, void 0, void 0, function* () {
            // account state (e.g. state provider framework keys -> account settings)
            const accounts = yield helper.getAccounts();
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
            // rollback account state
            function rollbackAccount(userId, account) {
                return _25_move_clear_clipboard_to_autofill_settings_state_provider_awaiter(this, void 0, void 0, function* () {
                    let settings = (account === null || account === void 0 ? void 0 : account.settings) || {};
                    const clearClipboardDelay = yield helper.getFromUser(userId, Object.assign(Object.assign({}, autofillSettingsLocalStateDefinition), { key: "clearClipboardDelay" }));
                    // update new settings and remove the account state provider framework keys for the rolled back values
                    if (clearClipboardDelay !== undefined) {
                        settings = Object.assign(Object.assign({}, settings), { clearClipboard: clearClipboardDelay });
                        yield helper.setToUser(userId, Object.assign(Object.assign({}, autofillSettingsLocalStateDefinition), { key: "clearClipboardDelay" }), null);
                        // commit updated settings to state
                        yield helper.set(userId, Object.assign(Object.assign({}, account), { settings }));
                    }
                });
            }
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/26-revert-move-last-sync-to-state-provider.ts
var _26_revert_move_last_sync_to_state_provider_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const _26_revert_move_last_sync_to_state_provider_LAST_SYNC_KEY = {
    key: "lastSync",
    stateDefinition: {
        name: "sync",
    },
};
class RevertLastSyncMigrator extends Migrator {
    rollback(helper) {
        return _26_revert_move_last_sync_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function rollbackAccount(userId, account) {
                return _26_revert_move_last_sync_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const value = (_a = account === null || account === void 0 ? void 0 : account.profile) === null || _a === void 0 ? void 0 : _a.lastSync;
                    yield helper.setToUser(userId, _26_revert_move_last_sync_to_state_provider_LAST_SYNC_KEY, value !== null && value !== void 0 ? value : null);
                    if (value != null) {
                        delete account.profile.lastSync;
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
        });
    }
    migrate(helper) {
        return _26_revert_move_last_sync_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _26_revert_move_last_sync_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const value = yield helper.getFromUser(userId, _26_revert_move_last_sync_to_state_provider_LAST_SYNC_KEY);
                    if (account) {
                        account.profile = Object.assign((_a = account.profile) !== null && _a !== void 0 ? _a : {}, {
                            lastSync: value,
                        });
                        yield helper.set(userId, account);
                    }
                    yield helper.setToUser(userId, _26_revert_move_last_sync_to_state_provider_LAST_SYNC_KEY, null);
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/27-move-badge-settings-to-state-providers.ts
var _27_move_badge_settings_to_state_providers_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const enableBadgeCounterKeyDefinition = {
    stateDefinition: {
        name: "badgeSettings",
    },
    key: "enableBadgeCounter",
};
class BadgeSettingsMigrator extends Migrator {
    migrate(helper) {
        return _27_move_badge_settings_to_state_providers_awaiter(this, void 0, void 0, function* () {
            // account state (e.g. account settings -> state provider framework keys)
            const accounts = yield helper.getAccounts();
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
            // migrate account state
            function migrateAccount(userId, account) {
                return _27_move_badge_settings_to_state_providers_awaiter(this, void 0, void 0, function* () {
                    const accountSettings = account === null || account === void 0 ? void 0 : account.settings;
                    if ((accountSettings === null || accountSettings === void 0 ? void 0 : accountSettings.disableBadgeCounter) != undefined) {
                        yield helper.setToUser(userId, enableBadgeCounterKeyDefinition, !accountSettings.disableBadgeCounter);
                        delete account.settings.disableBadgeCounter;
                        // update the state account settings with the migrated values deleted
                        yield helper.set(userId, account);
                    }
                });
            }
        });
    }
    rollback(helper) {
        return _27_move_badge_settings_to_state_providers_awaiter(this, void 0, void 0, function* () {
            // account state (e.g. state provider framework keys -> account settings)
            const accounts = yield helper.getAccounts();
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
            // rollback account state
            function rollbackAccount(userId, account) {
                return _27_move_badge_settings_to_state_providers_awaiter(this, void 0, void 0, function* () {
                    let settings = (account === null || account === void 0 ? void 0 : account.settings) || {};
                    const enableBadgeCounter = yield helper.getFromUser(userId, enableBadgeCounterKeyDefinition);
                    // update new settings and remove the account state provider framework keys for the rolled back values
                    if (enableBadgeCounter != undefined) {
                        settings = Object.assign(Object.assign({}, settings), { disableBadgeCounter: !enableBadgeCounter });
                        yield helper.setToUser(userId, enableBadgeCounterKeyDefinition, null);
                        // commit updated settings to state
                        yield helper.set(userId, Object.assign(Object.assign({}, account), { settings }));
                    }
                });
            }
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/28-move-biometric-unlock-to-state-providers.ts
var _28_move_biometric_unlock_to_state_providers_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const BIOMETRIC_UNLOCK_ENABLED = {
    key: "biometricUnlockEnabled",
    stateDefinition: { name: "biometricSettings" },
};
class MoveBiometricUnlockToStateProviders extends Migrator {
    migrate(helper) {
        return _28_move_biometric_unlock_to_state_providers_awaiter(this, void 0, void 0, function* () {
            const legacyAccounts = yield helper.getAccounts();
            yield Promise.all(legacyAccounts.map((_a) => _28_move_biometric_unlock_to_state_providers_awaiter(this, [_a], void 0, function* ({ userId, account }) {
                var _b, _c;
                if (account == null) {
                    return;
                }
                // Move account data
                if (((_b = account === null || account === void 0 ? void 0 : account.settings) === null || _b === void 0 ? void 0 : _b.biometricUnlock) != null) {
                    yield helper.setToUser(userId, BIOMETRIC_UNLOCK_ENABLED, account.settings.biometricUnlock);
                }
                // Delete old account data
                (_c = account === null || account === void 0 ? void 0 : account.settings) === null || _c === void 0 ? true : delete _c.biometricUnlock;
                yield helper.set(userId, account);
            })));
        });
    }
    rollback(helper) {
        return _28_move_biometric_unlock_to_state_providers_awaiter(this, void 0, void 0, function* () {
            function rollbackUser(userId, account) {
                return _28_move_biometric_unlock_to_state_providers_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const biometricUnlock = yield helper.getFromUser(userId, BIOMETRIC_UNLOCK_ENABLED);
                    if (biometricUnlock != null) {
                        account !== null && account !== void 0 ? account : (account = {});
                        (_a = account.settings) !== null && _a !== void 0 ? _a : (account.settings = {});
                        account.settings.biometricUnlock = biometricUnlock;
                        yield helper.setToUser(userId, BIOMETRIC_UNLOCK_ENABLED, null);
                        yield helper.set(userId, account);
                    }
                });
            }
            const accounts = yield helper.getAccounts();
            yield Promise.all(accounts.map(({ userId, account }) => rollbackUser(userId, account)));
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/29-move-user-notification-settings-to-state-provider.ts
var _29_move_user_notification_settings_to_state_provider_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

class UserNotificationSettingsKeyMigrator extends Migrator {
    migrate(helper) {
        return _29_move_user_notification_settings_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const globalState = yield helper.get("global");
            // disableAddLoginNotification -> enableAddedLoginPrompt
            if ((globalState === null || globalState === void 0 ? void 0 : globalState.disableAddLoginNotification) != null) {
                yield helper.setToGlobal({
                    stateDefinition: {
                        name: "userNotificationSettings",
                    },
                    key: "enableAddedLoginPrompt",
                }, !globalState.disableAddLoginNotification);
                // delete `disableAddLoginNotification` from state global
                delete globalState.disableAddLoginNotification;
                yield helper.set("global", globalState);
            }
            // disableChangedPasswordNotification -> enableChangedPasswordPrompt
            if ((globalState === null || globalState === void 0 ? void 0 : globalState.disableChangedPasswordNotification) != null) {
                yield helper.setToGlobal({
                    stateDefinition: {
                        name: "userNotificationSettings",
                    },
                    key: "enableChangedPasswordPrompt",
                }, !globalState.disableChangedPasswordNotification);
                // delete `disableChangedPasswordNotification` from state global
                delete globalState.disableChangedPasswordNotification;
                yield helper.set("global", globalState);
            }
        });
    }
    rollback(helper) {
        return _29_move_user_notification_settings_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const globalState = (yield helper.get("global")) || {};
            const enableAddedLoginPrompt = yield helper.getFromGlobal({
                stateDefinition: {
                    name: "userNotificationSettings",
                },
                key: "enableAddedLoginPrompt",
            });
            const enableChangedPasswordPrompt = yield helper.getFromGlobal({
                stateDefinition: {
                    name: "userNotificationSettings",
                },
                key: "enableChangedPasswordPrompt",
            });
            // enableAddedLoginPrompt -> disableAddLoginNotification
            if (enableAddedLoginPrompt) {
                yield helper.set("global", Object.assign(Object.assign({}, globalState), { disableAddLoginNotification: !enableAddedLoginPrompt }));
                // remove the global state provider framework key for `enableAddedLoginPrompt`
                yield helper.setToGlobal({
                    stateDefinition: {
                        name: "userNotificationSettings",
                    },
                    key: "enableAddedLoginPrompt",
                }, null);
            }
            // enableChangedPasswordPrompt -> disableChangedPasswordNotification
            if (enableChangedPasswordPrompt) {
                yield helper.set("global", Object.assign(Object.assign({}, globalState), { disableChangedPasswordNotification: !enableChangedPasswordPrompt }));
                // remove the global state provider framework key for `enableChangedPasswordPrompt`
                yield helper.setToGlobal({
                    stateDefinition: {
                        name: "userNotificationSettings",
                    },
                    key: "enableChangedPasswordPrompt",
                }, null);
            }
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/30-move-policy-state-to-state-provider.ts
var _30_move_policy_state_to_state_provider_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var _30_move_policy_state_to_state_provider_PolicyType;
(function (PolicyType) {
    PolicyType[PolicyType["TwoFactorAuthentication"] = 0] = "TwoFactorAuthentication";
    PolicyType[PolicyType["MasterPassword"] = 1] = "MasterPassword";
    PolicyType[PolicyType["PasswordGenerator"] = 2] = "PasswordGenerator";
    PolicyType[PolicyType["SingleOrg"] = 3] = "SingleOrg";
    PolicyType[PolicyType["RequireSso"] = 4] = "RequireSso";
    PolicyType[PolicyType["PersonalOwnership"] = 5] = "PersonalOwnership";
    PolicyType[PolicyType["DisableSend"] = 6] = "DisableSend";
    PolicyType[PolicyType["SendOptions"] = 7] = "SendOptions";
    PolicyType[PolicyType["ResetPassword"] = 8] = "ResetPassword";
    PolicyType[PolicyType["MaximumVaultTimeout"] = 9] = "MaximumVaultTimeout";
    PolicyType[PolicyType["DisablePersonalVaultExport"] = 10] = "DisablePersonalVaultExport";
    PolicyType[PolicyType["ActivateAutofill"] = 11] = "ActivateAutofill";
})(_30_move_policy_state_to_state_provider_PolicyType || (_30_move_policy_state_to_state_provider_PolicyType = {}));
const POLICIES_KEY = {
    key: "policies",
    stateDefinition: {
        name: "policies",
    },
};
class PolicyMigrator extends Migrator {
    migrate(helper) {
        return _30_move_policy_state_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _30_move_policy_state_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    var _a, _b;
                    const value = (_b = (_a = account === null || account === void 0 ? void 0 : account.data) === null || _a === void 0 ? void 0 : _a.policies) === null || _b === void 0 ? void 0 : _b.encrypted;
                    if (value != null) {
                        yield helper.setToUser(userId, POLICIES_KEY, value);
                        delete account.data.policies;
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all(accounts.map(({ userId, account }) => migrateAccount(userId, account)));
        });
    }
    rollback(helper) {
        return _30_move_policy_state_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function rollbackAccount(userId, account) {
                return _30_move_policy_state_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const value = yield helper.getFromUser(userId, POLICIES_KEY);
                    if (account) {
                        account.data = Object.assign((_a = account.data) !== null && _a !== void 0 ? _a : {}, {
                            policies: {
                                encrypted: value,
                            },
                        });
                        yield helper.set(userId, account);
                    }
                    yield helper.setToUser(userId, POLICIES_KEY, null);
                });
            }
            yield Promise.all(accounts.map(({ userId, account }) => rollbackAccount(userId, account)));
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/31-move-enable-context-menu-to-autofill-settings-state-provider.ts
var _31_move_enable_context_menu_to_autofill_settings_state_provider_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const enableContextMenuKeyDefinition = {
    stateDefinition: {
        name: "autofillSettings",
    },
    key: "enableContextMenu",
};
class EnableContextMenuMigrator extends Migrator {
    migrate(helper) {
        return _31_move_enable_context_menu_to_autofill_settings_state_provider_awaiter(this, void 0, void 0, function* () {
            const globalState = yield helper.get("global");
            // disableContextMenuItem -> enableContextMenu
            if ((globalState === null || globalState === void 0 ? void 0 : globalState.disableContextMenuItem) != null) {
                yield helper.setToGlobal(enableContextMenuKeyDefinition, !globalState.disableContextMenuItem);
                // delete `disableContextMenuItem` from state global
                delete globalState.disableContextMenuItem;
                yield helper.set("global", globalState);
            }
        });
    }
    rollback(helper) {
        return _31_move_enable_context_menu_to_autofill_settings_state_provider_awaiter(this, void 0, void 0, function* () {
            const globalState = (yield helper.get("global")) || {};
            const enableContextMenu = yield helper.getFromGlobal(enableContextMenuKeyDefinition);
            // enableContextMenu -> disableContextMenuItem
            if (enableContextMenu != null) {
                yield helper.set("global", Object.assign(Object.assign({}, globalState), { disableContextMenuItem: !enableContextMenu }));
                // remove the global state provider framework key for `enableContextMenu`
                yield helper.setToGlobal(enableContextMenuKeyDefinition, null);
            }
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/32-move-preferred-language.ts
var _32_move_preferred_language_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const LOCALE_KEY = {
    key: "locale",
    stateDefinition: {
        name: "translation",
    },
};
class PreferredLanguageMigrator extends Migrator {
    migrate(helper) {
        return _32_move_preferred_language_awaiter(this, void 0, void 0, function* () {
            // global state
            const global = yield helper.get("global");
            if (!(global === null || global === void 0 ? void 0 : global.locale)) {
                return;
            }
            yield helper.setToGlobal(LOCALE_KEY, global.locale);
            delete global.locale;
            yield helper.set("global", global);
        });
    }
    rollback(helper) {
        return _32_move_preferred_language_awaiter(this, void 0, void 0, function* () {
            var _a;
            const locale = yield helper.getFromGlobal(LOCALE_KEY);
            if (!locale) {
                return;
            }
            const global = (_a = (yield helper.get("global"))) !== null && _a !== void 0 ? _a : {};
            global.locale = locale;
            yield helper.set("global", global);
            yield helper.setToGlobal(LOCALE_KEY, null);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/33-move-app-id-to-state-providers.ts
var _33_move_app_id_to_state_providers_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const APP_ID_STORAGE_KEY = "appId";
const ANONYMOUS_APP_ID_STORAGE_KEY = "anonymousAppId";
const APP_ID_KEY = {
    key: APP_ID_STORAGE_KEY,
    stateDefinition: { name: "applicationId" },
};
const ANONYMOUS_APP_ID_KEY = {
    key: ANONYMOUS_APP_ID_STORAGE_KEY,
    stateDefinition: { name: "applicationId" },
};
class AppIdMigrator extends Migrator {
    migrate(helper) {
        return _33_move_app_id_to_state_providers_awaiter(this, void 0, void 0, function* () {
            const appId = yield helper.get(APP_ID_STORAGE_KEY);
            const anonymousAppId = yield helper.get(ANONYMOUS_APP_ID_STORAGE_KEY);
            if (appId != null) {
                yield helper.setToGlobal(APP_ID_KEY, appId);
                yield helper.set(APP_ID_STORAGE_KEY, null);
            }
            if (anonymousAppId != null) {
                yield helper.setToGlobal(ANONYMOUS_APP_ID_KEY, anonymousAppId);
                yield helper.set(ANONYMOUS_APP_ID_STORAGE_KEY, null);
            }
        });
    }
    rollback(helper) {
        return _33_move_app_id_to_state_providers_awaiter(this, void 0, void 0, function* () {
            const appId = yield helper.getFromGlobal(APP_ID_KEY);
            const anonymousAppId = yield helper.getFromGlobal(ANONYMOUS_APP_ID_KEY);
            if (appId != null) {
                yield helper.set(APP_ID_STORAGE_KEY, appId);
                yield helper.setToGlobal(APP_ID_KEY, null);
            }
            if (anonymousAppId != null) {
                yield helper.set(ANONYMOUS_APP_ID_STORAGE_KEY, anonymousAppId);
                yield helper.setToGlobal(ANONYMOUS_APP_ID_KEY, null);
            }
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/34-move-domain-settings-to-state-providers.ts
var _34_move_domain_settings_to_state_providers_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

// FIXME: Remove when updating file. Eslint update
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const UriMatchStrategy = {
    Domain: 0,
    Host: 1,
    StartsWith: 2,
    Exact: 3,
    RegularExpression: 4,
    Never: 5,
};
const defaultUriMatchStrategyDefinition = {
    stateDefinition: {
        name: "domainSettings",
    },
    key: "defaultUriMatchStrategy",
};
const equivalentDomainsDefinition = {
    stateDefinition: {
        name: "domainSettings",
    },
    key: "equivalentDomains",
};
const neverDomainsDefinition = {
    stateDefinition: {
        name: "domainSettings",
    },
    key: "neverDomains",
};
class DomainSettingsMigrator extends Migrator {
    migrate(helper) {
        return _34_move_domain_settings_to_state_providers_awaiter(this, void 0, void 0, function* () {
            let updateAccount = false;
            // global state ("neverDomains")
            const globalState = yield helper.get("global");
            if ((globalState === null || globalState === void 0 ? void 0 : globalState.neverDomains) != null) {
                yield helper.setToGlobal(neverDomainsDefinition, globalState.neverDomains);
                // delete `neverDomains` from state global
                delete globalState.neverDomains;
                yield helper.set("global", globalState);
            }
            // account state ("defaultUriMatch" and "settings.equivalentDomains")
            const accounts = yield helper.getAccounts();
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
            // migrate account state
            function migrateAccount(userId, account) {
                return _34_move_domain_settings_to_state_providers_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const accountSettings = account === null || account === void 0 ? void 0 : account.settings;
                    if ((accountSettings === null || accountSettings === void 0 ? void 0 : accountSettings.defaultUriMatch) != undefined) {
                        yield helper.setToUser(userId, defaultUriMatchStrategyDefinition, accountSettings.defaultUriMatch);
                        delete account.settings.defaultUriMatch;
                        updateAccount = true;
                    }
                    if (((_a = accountSettings === null || accountSettings === void 0 ? void 0 : accountSettings.settings) === null || _a === void 0 ? void 0 : _a.equivalentDomains) != undefined) {
                        yield helper.setToUser(userId, equivalentDomainsDefinition, accountSettings.settings.equivalentDomains);
                        delete account.settings.settings.equivalentDomains;
                        delete account.settings.settings;
                        updateAccount = true;
                    }
                    if (updateAccount) {
                        // update the state account settings with the migrated values deleted
                        yield helper.set(userId, account);
                    }
                });
            }
        });
    }
    rollback(helper) {
        return _34_move_domain_settings_to_state_providers_awaiter(this, void 0, void 0, function* () {
            let updateAccount = false;
            // global state ("neverDomains")
            const globalState = (yield helper.get("global")) || {};
            const neverDomains = yield helper.getFromGlobal(neverDomainsDefinition);
            if (neverDomains != null) {
                yield helper.set("global", Object.assign(Object.assign({}, globalState), { neverDomains: neverDomains }));
                // remove the global state provider framework key for `neverDomains`
                yield helper.setToGlobal(neverDomainsDefinition, null);
            }
            // account state ("defaultUriMatchStrategy" and "equivalentDomains")
            const accounts = yield helper.getAccounts();
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
            // rollback account state
            function rollbackAccount(userId, account) {
                return _34_move_domain_settings_to_state_providers_awaiter(this, void 0, void 0, function* () {
                    let settings = (account === null || account === void 0 ? void 0 : account.settings) || {};
                    const defaultUriMatchStrategy = yield helper.getFromUser(userId, defaultUriMatchStrategyDefinition);
                    const equivalentDomains = yield helper.getFromUser(userId, equivalentDomainsDefinition);
                    // update new settings and remove the account state provider framework keys for the rolled back values
                    if (defaultUriMatchStrategy != null) {
                        settings = Object.assign(Object.assign({}, settings), { defaultUriMatch: defaultUriMatchStrategy });
                        yield helper.setToUser(userId, defaultUriMatchStrategyDefinition, null);
                        updateAccount = true;
                    }
                    if (equivalentDomains != null) {
                        settings = Object.assign(Object.assign({}, settings), { settings: { equivalentDomains } });
                        yield helper.setToUser(userId, equivalentDomainsDefinition, null);
                        updateAccount = true;
                    }
                    // commit updated settings to state
                    if (updateAccount) {
                        yield helper.set(userId, Object.assign(Object.assign({}, account), { settings }));
                    }
                });
            }
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/35-move-theme-to-state-providers.ts
var _35_move_theme_to_state_providers_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const THEME_SELECTION = {
    key: "selection",
    stateDefinition: { name: "theming" },
};
class MoveThemeToStateProviderMigrator extends Migrator {
    migrate(helper) {
        return _35_move_theme_to_state_providers_awaiter(this, void 0, void 0, function* () {
            const legacyGlobalState = yield helper.get("global");
            const theme = legacyGlobalState === null || legacyGlobalState === void 0 ? void 0 : legacyGlobalState.theme;
            if (theme != null) {
                yield helper.setToGlobal(THEME_SELECTION, theme);
                delete legacyGlobalState.theme;
                yield helper.set("global", legacyGlobalState);
            }
        });
    }
    rollback(helper) {
        return _35_move_theme_to_state_providers_awaiter(this, void 0, void 0, function* () {
            var _a;
            const theme = yield helper.getFromGlobal(THEME_SELECTION);
            if (theme != null) {
                const legacyGlobal = (_a = (yield helper.get("global"))) !== null && _a !== void 0 ? _a : {};
                legacyGlobal.theme = theme;
                yield helper.set("global", legacyGlobal);
                yield helper.removeFromGlobal(THEME_SELECTION);
            }
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/36-move-show-card-and-identity-to-state-provider.ts
var _36_move_show_card_and_identity_to_state_provider_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const vaultSettingsStateDefinition = {
    stateDefinition: {
        name: "vaultSettings",
    },
};
class VaultSettingsKeyMigrator extends Migrator {
    migrate(helper) {
        return _36_move_show_card_and_identity_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
            function migrateAccount(userId, account) {
                return _36_move_show_card_and_identity_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    let updateAccount = false;
                    const accountSettings = account === null || account === void 0 ? void 0 : account.settings;
                    if ((accountSettings === null || accountSettings === void 0 ? void 0 : accountSettings.dontShowCardsCurrentTab) != null) {
                        yield helper.setToUser(userId, Object.assign(Object.assign({}, vaultSettingsStateDefinition), { key: "showCardsCurrentTab" }), !accountSettings.dontShowCardsCurrentTab);
                        delete account.settings.dontShowCardsCurrentTab;
                        updateAccount = true;
                    }
                    if ((accountSettings === null || accountSettings === void 0 ? void 0 : accountSettings.dontShowIdentitiesCurrentTab) != null) {
                        yield helper.setToUser(userId, Object.assign(Object.assign({}, vaultSettingsStateDefinition), { key: "showIdentitiesCurrentTab" }), !accountSettings.dontShowIdentitiesCurrentTab);
                        delete account.settings.dontShowIdentitiesCurrentTab;
                        updateAccount = true;
                    }
                    if (updateAccount) {
                        yield helper.set(userId, account);
                    }
                });
            }
        });
    }
    rollback(helper) {
        return _36_move_show_card_and_identity_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
            function rollbackAccount(userId, account) {
                return _36_move_show_card_and_identity_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    let updateAccount = false;
                    let settings = (_a = account === null || account === void 0 ? void 0 : account.settings) !== null && _a !== void 0 ? _a : {};
                    const showCardsCurrentTab = yield helper.getFromUser(userId, Object.assign(Object.assign({}, vaultSettingsStateDefinition), { key: "showCardsCurrentTab" }));
                    const showIdentitiesCurrentTab = yield helper.getFromUser(userId, Object.assign(Object.assign({}, vaultSettingsStateDefinition), { key: "showIdentitiesCurrentTab" }));
                    if (showCardsCurrentTab != null) {
                        // invert the value to match the new naming convention
                        settings = Object.assign(Object.assign({}, settings), { dontShowCardsCurrentTab: !showCardsCurrentTab });
                        yield helper.setToUser(userId, Object.assign(Object.assign({}, vaultSettingsStateDefinition), { key: "showCardsCurrentTab" }), null);
                        updateAccount = true;
                    }
                    if (showIdentitiesCurrentTab != null) {
                        // invert the value to match the new naming convention
                        settings = Object.assign(Object.assign({}, settings), { dontShowIdentitiesCurrentTab: !showIdentitiesCurrentTab });
                        yield helper.setToUser(userId, Object.assign(Object.assign({}, vaultSettingsStateDefinition), { key: "showIdentitiesCurrentTab" }), null);
                        updateAccount = true;
                    }
                    if (updateAccount) {
                        yield helper.set(userId, Object.assign(Object.assign({}, account), { settings }));
                    }
                });
            }
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/37-move-avatar-color-to-state-providers.ts
var _37_move_avatar_color_to_state_providers_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const AVATAR_COLOR_STATE = { name: "avatar" };
const AVATAR_COLOR_KEY = {
    key: "avatarColor",
    stateDefinition: AVATAR_COLOR_STATE,
};
class AvatarColorMigrator extends Migrator {
    migrate(helper) {
        return _37_move_avatar_color_to_state_providers_awaiter(this, void 0, void 0, function* () {
            const legacyAccounts = yield helper.getAccounts();
            yield Promise.all(legacyAccounts.map((_a) => _37_move_avatar_color_to_state_providers_awaiter(this, [_a], void 0, function* ({ userId, account }) {
                var _b, _c;
                // Move account avatarColor
                if (((_b = account === null || account === void 0 ? void 0 : account.settings) === null || _b === void 0 ? void 0 : _b.avatarColor) != null) {
                    yield helper.setToUser(userId, AVATAR_COLOR_KEY, account.settings.avatarColor);
                    // Delete old account avatarColor property
                    (_c = account === null || account === void 0 ? void 0 : account.settings) === null || _c === void 0 ? true : delete _c.avatarColor;
                    yield helper.set(userId, account);
                }
            })));
        });
    }
    rollback(helper) {
        return _37_move_avatar_color_to_state_providers_awaiter(this, void 0, void 0, function* () {
            function rollbackUser(userId, account) {
                return _37_move_avatar_color_to_state_providers_awaiter(this, void 0, void 0, function* () {
                    let updatedAccount = false;
                    const userAvatarColor = yield helper.getFromUser(userId, AVATAR_COLOR_KEY);
                    if (userAvatarColor) {
                        if (!account) {
                            account = {};
                        }
                        updatedAccount = true;
                        account.settings.avatarColor = userAvatarColor;
                        yield helper.setToUser(userId, AVATAR_COLOR_KEY, null);
                    }
                    if (updatedAccount) {
                        yield helper.set(userId, account);
                    }
                });
            }
            const accounts = yield helper.getAccounts();
            yield Promise.all(accounts.map(({ userId, account }) => rollbackUser(userId, account)));
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/38-migrate-token-svc-to-state-provider.ts
var _38_migrate_token_svc_to_state_provider_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const EMAIL_TWO_FACTOR_TOKEN_RECORD_DISK_LOCAL = {
    key: "emailTwoFactorTokenRecord",
    stateDefinition: {
        name: "tokenDiskLocal",
    },
};
const TOKEN_STATE_DEF_LIKE = {
    name: "token",
};
const ACCESS_TOKEN_DISK = {
    key: "accessToken", // matches KeyDefinition.key
    stateDefinition: TOKEN_STATE_DEF_LIKE,
};
const REFRESH_TOKEN_DISK = {
    key: "refreshToken",
    stateDefinition: TOKEN_STATE_DEF_LIKE,
};
const API_KEY_CLIENT_ID_DISK = {
    key: "apiKeyClientId",
    stateDefinition: TOKEN_STATE_DEF_LIKE,
};
const API_KEY_CLIENT_SECRET_DISK = {
    key: "apiKeyClientSecret",
    stateDefinition: TOKEN_STATE_DEF_LIKE,
};
class TokenServiceStateProviderMigrator extends Migrator {
    migrate(helper) {
        return _38_migrate_token_svc_to_state_provider_awaiter(this, void 0, void 0, function* () {
            // Move global data
            const globalData = yield helper.get("global");
            // Create new global record for 2FA token that we can accumulate data in
            const emailTwoFactorTokenRecord = {};
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account, globalTwoFactorToken, emailTwoFactorTokenRecord) {
                return _38_migrate_token_svc_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    var _a, _b, _c, _d, _e;
                    let updatedAccount = false;
                    // migrate 2FA token from global to user state
                    // Due to the existing implmentation, n users on the same device share the same global state value for 2FA token.
                    // So, we will just migrate it to all users to keep it valid for whichever was the user that set it previously.
                    // Note: don't bother migrating 2FA Token if user account or email is undefined
                    const email = (_a = account === null || account === void 0 ? void 0 : account.profile) === null || _a === void 0 ? void 0 : _a.email;
                    if (globalTwoFactorToken != undefined && account != undefined && email != undefined) {
                        emailTwoFactorTokenRecord[email] = globalTwoFactorToken;
                        // Note: don't set updatedAccount to true here as we aren't updating
                        // the legacy user state, just migrating a global state to a new user state
                    }
                    // Migrate access token
                    const existingAccessToken = (_b = account === null || account === void 0 ? void 0 : account.tokens) === null || _b === void 0 ? void 0 : _b.accessToken;
                    if (existingAccessToken != null) {
                        // Only migrate data that exists
                        if (helper.type !== "web-disk-local") {
                            // only migrate access token to session storage - never local.
                            yield helper.setToUser(userId, ACCESS_TOKEN_DISK, existingAccessToken);
                        }
                        delete account.tokens.accessToken;
                        updatedAccount = true;
                    }
                    // Migrate refresh token
                    const existingRefreshToken = (_c = account === null || account === void 0 ? void 0 : account.tokens) === null || _c === void 0 ? void 0 : _c.refreshToken;
                    if (existingRefreshToken != null) {
                        if (helper.type !== "web-disk-local") {
                            // only migrate refresh token to session storage - never local.
                            yield helper.setToUser(userId, REFRESH_TOKEN_DISK, existingRefreshToken);
                        }
                        delete account.tokens.refreshToken;
                        updatedAccount = true;
                    }
                    // Migrate API key client id
                    const existingApiKeyClientId = (_d = account === null || account === void 0 ? void 0 : account.profile) === null || _d === void 0 ? void 0 : _d.apiKeyClientId;
                    if (existingApiKeyClientId != null) {
                        if (helper.type !== "web-disk-local") {
                            // only migrate client id to session storage - never local.
                            yield helper.setToUser(userId, API_KEY_CLIENT_ID_DISK, existingApiKeyClientId);
                        }
                        delete account.profile.apiKeyClientId;
                        updatedAccount = true;
                    }
                    // Migrate API key client secret
                    const existingApiKeyClientSecret = (_e = account === null || account === void 0 ? void 0 : account.keys) === null || _e === void 0 ? void 0 : _e.apiKeyClientSecret;
                    if (existingApiKeyClientSecret != null) {
                        if (helper.type !== "web-disk-local") {
                            // only migrate client secret to session storage - never local.
                            yield helper.setToUser(userId, API_KEY_CLIENT_SECRET_DISK, existingApiKeyClientSecret);
                        }
                        delete account.keys.apiKeyClientSecret;
                        updatedAccount = true;
                    }
                    if (updatedAccount) {
                        // Save the migrated account only if it was updated
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all([
                ...accounts.map(({ userId, account }) => migrateAccount(userId, account, globalData === null || globalData === void 0 ? void 0 : globalData.twoFactorToken, emailTwoFactorTokenRecord)),
            ]);
            // Save the global 2FA token record
            yield helper.setToGlobal(EMAIL_TWO_FACTOR_TOKEN_RECORD_DISK_LOCAL, emailTwoFactorTokenRecord);
            // Delete global data
            globalData === null || globalData === void 0 ? true : delete globalData.twoFactorToken;
            yield helper.set("global", globalData);
        });
    }
    rollback(helper) {
        return _38_migrate_token_svc_to_state_provider_awaiter(this, void 0, void 0, function* () {
            var _a;
            const accounts = yield helper.getAccounts();
            // Since we migrated the global 2FA token to all users, we need to rollback the 2FA token for all users
            // but we only need to set it to the global state once
            // Go through accounts and find the first user that has a non-null email and 2FA token
            let migratedTwoFactorToken = null;
            for (const { account } of accounts) {
                const email = (_a = account === null || account === void 0 ? void 0 : account.profile) === null || _a === void 0 ? void 0 : _a.email;
                if (email == null) {
                    continue;
                }
                const emailTwoFactorTokenRecord = yield helper.getFromGlobal(EMAIL_TWO_FACTOR_TOKEN_RECORD_DISK_LOCAL);
                migratedTwoFactorToken = emailTwoFactorTokenRecord[email];
                if (migratedTwoFactorToken != null) {
                    break;
                }
            }
            if (migratedTwoFactorToken != null) {
                let legacyGlobal = yield helper.get("global");
                if (!legacyGlobal) {
                    legacyGlobal = {};
                }
                legacyGlobal.twoFactorToken = migratedTwoFactorToken;
                yield helper.set("global", legacyGlobal);
            }
            // delete global 2FA token record
            yield helper.setToGlobal(EMAIL_TWO_FACTOR_TOKEN_RECORD_DISK_LOCAL, null);
            function rollbackAccount(userId, account) {
                return _38_migrate_token_svc_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    let updatedLegacyAccount = false;
                    // Rollback access token
                    const migratedAccessToken = yield helper.getFromUser(userId, ACCESS_TOKEN_DISK);
                    if ((account === null || account === void 0 ? void 0 : account.tokens) && migratedAccessToken != null) {
                        account.tokens.accessToken = migratedAccessToken;
                        updatedLegacyAccount = true;
                    }
                    yield helper.setToUser(userId, ACCESS_TOKEN_DISK, null);
                    // Rollback refresh token
                    const migratedRefreshToken = yield helper.getFromUser(userId, REFRESH_TOKEN_DISK);
                    if ((account === null || account === void 0 ? void 0 : account.tokens) && migratedRefreshToken != null) {
                        account.tokens.refreshToken = migratedRefreshToken;
                        updatedLegacyAccount = true;
                    }
                    yield helper.setToUser(userId, REFRESH_TOKEN_DISK, null);
                    // Rollback API key client id
                    const migratedApiKeyClientId = yield helper.getFromUser(userId, API_KEY_CLIENT_ID_DISK);
                    if ((account === null || account === void 0 ? void 0 : account.profile) && migratedApiKeyClientId != null) {
                        account.profile.apiKeyClientId = migratedApiKeyClientId;
                        updatedLegacyAccount = true;
                    }
                    yield helper.setToUser(userId, API_KEY_CLIENT_ID_DISK, null);
                    // Rollback API key client secret
                    const migratedApiKeyClientSecret = yield helper.getFromUser(userId, API_KEY_CLIENT_SECRET_DISK);
                    if ((account === null || account === void 0 ? void 0 : account.keys) && migratedApiKeyClientSecret != null) {
                        account.keys.apiKeyClientSecret = migratedApiKeyClientSecret;
                        updatedLegacyAccount = true;
                    }
                    yield helper.setToUser(userId, API_KEY_CLIENT_SECRET_DISK, null);
                    if (updatedLegacyAccount) {
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/39-move-billing-account-profile-to-state-providers.ts
var _39_move_billing_account_profile_to_state_providers_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const BILLING_ACCOUNT_PROFILE_KEY_DEFINITION = {
    key: "accountProfile",
    stateDefinition: {
        name: "billing",
    },
};
class MoveBillingAccountProfileMigrator extends Migrator {
    migrate(helper) {
        return _39_move_billing_account_profile_to_state_providers_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            const migrateAccount = (userId, account) => _39_move_billing_account_profile_to_state_providers_awaiter(this, void 0, void 0, function* () {
                var _a, _b, _c, _d;
                const hasPremiumPersonally = (_a = account === null || account === void 0 ? void 0 : account.profile) === null || _a === void 0 ? void 0 : _a.hasPremiumPersonally;
                const hasPremiumFromOrganization = (_b = account === null || account === void 0 ? void 0 : account.profile) === null || _b === void 0 ? void 0 : _b.hasPremiumFromOrganization;
                if (hasPremiumPersonally != null || hasPremiumFromOrganization != null) {
                    yield helper.setToUser(userId, BILLING_ACCOUNT_PROFILE_KEY_DEFINITION, {
                        hasPremiumPersonally: hasPremiumPersonally,
                        hasPremiumFromOrganization: hasPremiumFromOrganization,
                    });
                    (_c = account === null || account === void 0 ? void 0 : account.profile) === null || _c === void 0 ? true : delete _c.hasPremiumPersonally;
                    (_d = account === null || account === void 0 ? void 0 : account.profile) === null || _d === void 0 ? true : delete _d.hasPremiumFromOrganization;
                    yield helper.set(userId, account);
                }
            });
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
    rollback(helper) {
        return _39_move_billing_account_profile_to_state_providers_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            const rollbackAccount = (userId, account) => _39_move_billing_account_profile_to_state_providers_awaiter(this, void 0, void 0, function* () {
                var _a;
                const value = yield helper.getFromUser(userId, BILLING_ACCOUNT_PROFILE_KEY_DEFINITION);
                if (account && value) {
                    account.profile = Object.assign((_a = account.profile) !== null && _a !== void 0 ? _a : {}, {
                        hasPremiumPersonally: value === null || value === void 0 ? void 0 : value.hasPremiumPersonally,
                        hasPremiumFromOrganization: value === null || value === void 0 ? void 0 : value.hasPremiumFromOrganization,
                    });
                    yield helper.set(userId, account);
                }
                yield helper.setToUser(userId, BILLING_ACCOUNT_PROFILE_KEY_DEFINITION, null);
            });
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/4-remove-ever-been-unlocked.ts
var _4_remove_ever_been_unlocked_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

class RemoveEverBeenUnlockedMigrator extends Migrator {
    migrate(helper) {
        return _4_remove_ever_been_unlocked_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function removeEverBeenUnlocked(userId, account) {
                return _4_remove_ever_been_unlocked_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    if (((_a = account === null || account === void 0 ? void 0 : account.profile) === null || _a === void 0 ? void 0 : _a.everBeenUnlocked) != null) {
                        delete account.profile.everBeenUnlocked;
                        return helper.set(userId, account);
                    }
                });
            }
            // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
            // eslint-disable-next-line @typescript-eslint/no-floating-promises
            Promise.all(accounts.map(({ userId, account }) => removeEverBeenUnlocked(userId, account)));
        });
    }
    rollback(helper) {
        throw IRREVERSIBLE;
    }
    // Override is necessary because default implementation assumes `stateVersion` at the root, but for this version
    // it is nested inside a global object.
    updateVersion(helper, direction) {
        return _4_remove_ever_been_unlocked_awaiter(this, void 0, void 0, function* () {
            const endVersion = direction === "up" ? this.toVersion : this.fromVersion;
            helper.currentVersion = endVersion;
            const global = (yield helper.get("global")) || {};
            yield helper.set("global", Object.assign(Object.assign({}, global), { stateVersion: endVersion }));
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/40-move-organization-state-to-state-provider.ts
var _40_move_organization_state_to_state_provider_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

// Local declarations of `OrganizationData` and the types of it's properties.
// Duplicated to remain frozen in time when migration occurs.
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var OrganizationUserStatusType;
(function (OrganizationUserStatusType) {
    OrganizationUserStatusType[OrganizationUserStatusType["Invited"] = 0] = "Invited";
    OrganizationUserStatusType[OrganizationUserStatusType["Accepted"] = 1] = "Accepted";
    OrganizationUserStatusType[OrganizationUserStatusType["Confirmed"] = 2] = "Confirmed";
    OrganizationUserStatusType[OrganizationUserStatusType["Revoked"] = -1] = "Revoked";
})(OrganizationUserStatusType || (OrganizationUserStatusType = {}));
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var OrganizationUserType;
(function (OrganizationUserType) {
    OrganizationUserType[OrganizationUserType["Owner"] = 0] = "Owner";
    OrganizationUserType[OrganizationUserType["Admin"] = 1] = "Admin";
    OrganizationUserType[OrganizationUserType["User"] = 2] = "User";
    OrganizationUserType[OrganizationUserType["Manager"] = 3] = "Manager";
    OrganizationUserType[OrganizationUserType["Custom"] = 4] = "Custom";
})(OrganizationUserType || (OrganizationUserType = {}));
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var ProviderType;
(function (ProviderType) {
    ProviderType[ProviderType["Msp"] = 0] = "Msp";
    ProviderType[ProviderType["Reseller"] = 1] = "Reseller";
})(ProviderType || (ProviderType = {}));
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var ProductType;
(function (ProductType) {
    ProductType[ProductType["Free"] = 0] = "Free";
    ProductType[ProductType["Families"] = 1] = "Families";
    ProductType[ProductType["Teams"] = 2] = "Teams";
    ProductType[ProductType["Enterprise"] = 3] = "Enterprise";
    ProductType[ProductType["TeamsStarter"] = 4] = "TeamsStarter";
})(ProductType || (ProductType = {}));
const USER_ORGANIZATIONS = {
    key: "organizations",
    stateDefinition: {
        name: "organizations",
    },
};
class OrganizationMigrator extends Migrator {
    migrate(helper) {
        return _40_move_organization_state_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _40_move_organization_state_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const value = (_a = account === null || account === void 0 ? void 0 : account.data) === null || _a === void 0 ? void 0 : _a.organizations;
                    if (value != null) {
                        yield helper.setToUser(userId, USER_ORGANIZATIONS, value);
                        delete account.data.organizations;
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all(accounts.map(({ userId, account }) => migrateAccount(userId, account)));
        });
    }
    rollback(helper) {
        return _40_move_organization_state_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function rollbackAccount(userId, account) {
                return _40_move_organization_state_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const value = yield helper.getFromUser(userId, USER_ORGANIZATIONS);
                    if (account) {
                        account.data = Object.assign((_a = account.data) !== null && _a !== void 0 ? _a : {}, {
                            organizations: value,
                        });
                        yield helper.set(userId, account);
                    }
                    yield helper.setToUser(userId, USER_ORGANIZATIONS, null);
                });
            }
            yield Promise.all(accounts.map(({ userId, account }) => rollbackAccount(userId, account)));
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/41-move-event-collection-to-state-provider.ts
var _41_move_event_collection_to_state_provider_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const EVENT_COLLECTION = {
    stateDefinition: {
        name: "eventCollection",
    },
    key: "eventCollection",
};
class EventCollectionMigrator extends Migrator {
    migrate(helper) {
        return _41_move_event_collection_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _41_move_event_collection_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const value = (_a = account === null || account === void 0 ? void 0 : account.data) === null || _a === void 0 ? void 0 : _a.eventCollection;
                    if (value != null) {
                        yield helper.setToUser(userId, EVENT_COLLECTION, value);
                        delete account.data.eventCollection;
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
    rollback(helper) {
        return _41_move_event_collection_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function rollbackAccount(userId, account) {
                return _41_move_event_collection_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const value = yield helper.getFromUser(userId, EVENT_COLLECTION);
                    if (account) {
                        account.data = Object.assign((_a = account.data) !== null && _a !== void 0 ? _a : {}, {
                            eventCollection: value,
                        });
                        yield helper.set(userId, account);
                    }
                    yield helper.setToUser(userId, EVENT_COLLECTION, null);
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/42-move-enable-favicon-to-domain-settings-state-provider.ts
var _42_move_enable_favicon_to_domain_settings_state_provider_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const ShowFaviconDefinition = {
    stateDefinition: {
        name: "domainSettings",
    },
    key: "showFavicons",
};
class EnableFaviconMigrator extends Migrator {
    migrate(helper) {
        return _42_move_enable_favicon_to_domain_settings_state_provider_awaiter(this, void 0, void 0, function* () {
            // global state ("disableFavicon" -> "showFavicons")
            const globalState = yield helper.get("global");
            if ((globalState === null || globalState === void 0 ? void 0 : globalState.disableFavicon) != null) {
                yield helper.setToGlobal(ShowFaviconDefinition, !globalState.disableFavicon);
                // delete `disableFavicon` from state global
                delete globalState.disableFavicon;
                yield helper.set("global", globalState);
            }
        });
    }
    rollback(helper) {
        return _42_move_enable_favicon_to_domain_settings_state_provider_awaiter(this, void 0, void 0, function* () {
            // global state ("showFavicons" -> "disableFavicon")
            const globalState = (yield helper.get("global")) || {};
            const showFavicons = yield helper.getFromGlobal(ShowFaviconDefinition);
            if (showFavicons != null) {
                yield helper.set("global", Object.assign(Object.assign({}, globalState), { disableFavicon: !showFavicons }));
                // remove the global state provider framework key for `showFavicons`
                yield helper.setToGlobal(ShowFaviconDefinition, null);
            }
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/43-move-auto-confirm-finger-prints-to-state-provider.ts
var _43_move_auto_confirm_finger_prints_to_state_provider_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const ORGANIZATION_MANAGEMENT_PREFERENCES = {
    name: "organizationManagementPreferences",
};
const AUTO_CONFIRM_FINGERPRINTS = {
    key: "autoConfirmFingerPrints",
    stateDefinition: ORGANIZATION_MANAGEMENT_PREFERENCES,
};
class AutoConfirmFingerPrintsMigrator extends Migrator {
    migrate(helper) {
        return _43_move_auto_confirm_finger_prints_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const legacyAccounts = yield helper.getAccounts();
            yield Promise.all(legacyAccounts.map((_a) => _43_move_auto_confirm_finger_prints_to_state_provider_awaiter(this, [_a], void 0, function* ({ userId, account }) {
                var _b, _c;
                if (((_b = account === null || account === void 0 ? void 0 : account.settings) === null || _b === void 0 ? void 0 : _b.autoConfirmFingerPrints) != null) {
                    yield helper.setToUser(userId, AUTO_CONFIRM_FINGERPRINTS, account.settings.autoConfirmFingerPrints);
                    (_c = account === null || account === void 0 ? void 0 : account.settings) === null || _c === void 0 ? true : delete _c.autoConfirmFingerPrints;
                    yield helper.set(userId, account);
                }
            })));
        });
    }
    rollback(helper) {
        return _43_move_auto_confirm_finger_prints_to_state_provider_awaiter(this, void 0, void 0, function* () {
            function rollbackUser(userId, account) {
                return _43_move_auto_confirm_finger_prints_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    let updatedAccount = false;
                    const autoConfirmFingerPrints = yield helper.getFromUser(userId, AUTO_CONFIRM_FINGERPRINTS);
                    if (autoConfirmFingerPrints) {
                        if (!account) {
                            account = {};
                        }
                        updatedAccount = true;
                        account.settings.autoConfirmFingerPrints = autoConfirmFingerPrints;
                        yield helper.setToUser(userId, AUTO_CONFIRM_FINGERPRINTS, null);
                    }
                    if (updatedAccount) {
                        yield helper.set(userId, account);
                    }
                });
            }
            const accounts = yield helper.getAccounts();
            yield Promise.all(accounts.map(({ userId, account }) => rollbackUser(userId, account)));
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/44-move-user-decryption-options-to-state-provider.ts
var _44_move_user_decryption_options_to_state_provider_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const USER_DECRYPTION_OPTIONS = {
    key: "decryptionOptions",
    stateDefinition: {
        name: "userDecryptionOptions",
    },
};
class UserDecryptionOptionsMigrator extends Migrator {
    migrate(helper) {
        return _44_move_user_decryption_options_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _44_move_user_decryption_options_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    const value = account === null || account === void 0 ? void 0 : account.decryptionOptions;
                    if (value != null) {
                        yield helper.setToUser(userId, USER_DECRYPTION_OPTIONS, value);
                        delete account.decryptionOptions;
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
    rollback(helper) {
        return _44_move_user_decryption_options_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function rollbackAccount(userId, account) {
                return _44_move_user_decryption_options_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    const value = yield helper.getFromUser(userId, USER_DECRYPTION_OPTIONS);
                    if (account) {
                        account.decryptionOptions = Object.assign(account.decryptionOptions, value);
                        yield helper.set(userId, account);
                    }
                    yield helper.setToUser(userId, USER_DECRYPTION_OPTIONS, null);
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/45-merge-environment-state.ts
var _45_merge_environment_state_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const _45_merge_environment_state_ENVIRONMENT_STATE = { name: "environment" };
const ENVIRONMENT_REGION = {
    key: "region",
    stateDefinition: _45_merge_environment_state_ENVIRONMENT_STATE,
};
const ENVIRONMENT_URLS = {
    key: "urls",
    stateDefinition: _45_merge_environment_state_ENVIRONMENT_STATE,
};
const ENVIRONMENT_ENVIRONMENT = {
    key: "environment",
    stateDefinition: _45_merge_environment_state_ENVIRONMENT_STATE,
};
class MergeEnvironmentState extends Migrator {
    migrate(helper) {
        return _45_merge_environment_state_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _45_merge_environment_state_awaiter(this, void 0, void 0, function* () {
                    const region = yield helper.getFromUser(userId, ENVIRONMENT_REGION);
                    const urls = yield helper.getFromUser(userId, ENVIRONMENT_URLS);
                    if (region == null && urls == null) {
                        return;
                    }
                    yield helper.setToUser(userId, ENVIRONMENT_ENVIRONMENT, {
                        region,
                        urls,
                    });
                    yield helper.removeFromUser(userId, ENVIRONMENT_REGION);
                    yield helper.removeFromUser(userId, ENVIRONMENT_URLS);
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
            const region = yield helper.getFromGlobal(ENVIRONMENT_REGION);
            const urls = yield helper.getFromGlobal(ENVIRONMENT_URLS);
            if (region == null && urls == null) {
                return;
            }
            yield helper.setToGlobal(ENVIRONMENT_ENVIRONMENT, {
                region,
                urls,
            });
            yield helper.removeFromGlobal(ENVIRONMENT_REGION);
            yield helper.removeFromGlobal(ENVIRONMENT_URLS);
        });
    }
    rollback(helper) {
        return _45_merge_environment_state_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function rollbackAccount(userId, account) {
                return _45_merge_environment_state_awaiter(this, void 0, void 0, function* () {
                    const state = (yield helper.getFromUser(userId, ENVIRONMENT_ENVIRONMENT));
                    yield helper.setToUser(userId, ENVIRONMENT_REGION, state === null || state === void 0 ? void 0 : state.region);
                    yield helper.setToUser(userId, ENVIRONMENT_URLS, state === null || state === void 0 ? void 0 : state.urls);
                    yield helper.removeFromUser(userId, ENVIRONMENT_ENVIRONMENT);
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
            const state = (yield helper.getFromGlobal(ENVIRONMENT_ENVIRONMENT));
            yield helper.setToGlobal(ENVIRONMENT_REGION, state === null || state === void 0 ? void 0 : state.region);
            yield helper.setToGlobal(ENVIRONMENT_URLS, state === null || state === void 0 ? void 0 : state.urls);
            yield helper.removeFromGlobal(ENVIRONMENT_ENVIRONMENT);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/46-delete-orphaned-biometric-prompt-data.ts
var _46_delete_orphaned_biometric_prompt_data_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const PROMPT_CANCELLED = {
    key: "promptCancelled",
    stateDefinition: { name: "biometricSettings" },
};
class DeleteBiometricPromptCancelledData extends Migrator {
    migrate(helper) {
        return _46_delete_orphaned_biometric_prompt_data_awaiter(this, void 0, void 0, function* () {
            yield Promise.all((yield helper.getAccounts()).map((_a) => _46_delete_orphaned_biometric_prompt_data_awaiter(this, [_a], void 0, function* ({ userId }) {
                if (helper.getFromUser(userId, PROMPT_CANCELLED) != null) {
                    yield helper.removeFromUser(userId, PROMPT_CANCELLED);
                }
            })));
        });
    }
    rollback(helper) {
        return _46_delete_orphaned_biometric_prompt_data_awaiter(this, void 0, void 0, function* () {
            throw IRREVERSIBLE;
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/47-move-desktop-settings.ts
var _47_move_desktop_settings_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const DESKTOP_SETTINGS_STATE = { name: "desktopSettings" };
const WINDOW_KEY = { key: "window", stateDefinition: DESKTOP_SETTINGS_STATE };
const CLOSE_TO_TRAY_KEY = {
    key: "closeToTray",
    stateDefinition: DESKTOP_SETTINGS_STATE,
};
const MINIMIZE_TO_TRAY_KEY = {
    key: "minimizeToTray",
    stateDefinition: DESKTOP_SETTINGS_STATE,
};
const START_TO_TRAY_KEY = {
    key: "startToTray",
    stateDefinition: DESKTOP_SETTINGS_STATE,
};
const TRAY_ENABLED_KEY = {
    key: "trayEnabled",
    stateDefinition: DESKTOP_SETTINGS_STATE,
};
const OPEN_AT_LOGIN_KEY = {
    key: "openAtLogin",
    stateDefinition: DESKTOP_SETTINGS_STATE,
};
const ALWAYS_SHOW_DOCK_KEY = {
    key: "alwaysShowDock",
    stateDefinition: DESKTOP_SETTINGS_STATE,
};
const ALWAYS_ON_TOP_KEY = {
    key: "alwaysOnTop",
    stateDefinition: DESKTOP_SETTINGS_STATE,
};
class MoveDesktopSettingsMigrator extends Migrator {
    migrate(helper) {
        return _47_move_desktop_settings_awaiter(this, void 0, void 0, function* () {
            const legacyGlobal = yield helper.get("global");
            let updatedGlobal = false;
            if ((legacyGlobal === null || legacyGlobal === void 0 ? void 0 : legacyGlobal.window) !== undefined) {
                yield helper.setToGlobal(WINDOW_KEY, legacyGlobal.window);
                updatedGlobal = true;
                delete legacyGlobal.window;
            }
            if ((legacyGlobal === null || legacyGlobal === void 0 ? void 0 : legacyGlobal.enableCloseToTray) != null) {
                yield helper.setToGlobal(CLOSE_TO_TRAY_KEY, legacyGlobal.enableCloseToTray);
                updatedGlobal = true;
                delete legacyGlobal.enableCloseToTray;
            }
            if ((legacyGlobal === null || legacyGlobal === void 0 ? void 0 : legacyGlobal.enableMinimizeToTray) != null) {
                yield helper.setToGlobal(MINIMIZE_TO_TRAY_KEY, legacyGlobal.enableMinimizeToTray);
                updatedGlobal = true;
                delete legacyGlobal.enableMinimizeToTray;
            }
            if ((legacyGlobal === null || legacyGlobal === void 0 ? void 0 : legacyGlobal.enableStartToTray) != null) {
                yield helper.setToGlobal(START_TO_TRAY_KEY, legacyGlobal.enableStartToTray);
                updatedGlobal = true;
                delete legacyGlobal.enableStartToTray;
            }
            if ((legacyGlobal === null || legacyGlobal === void 0 ? void 0 : legacyGlobal.enableTray) != null) {
                yield helper.setToGlobal(TRAY_ENABLED_KEY, legacyGlobal.enableTray);
                updatedGlobal = true;
                delete legacyGlobal.enableTray;
            }
            if ((legacyGlobal === null || legacyGlobal === void 0 ? void 0 : legacyGlobal.openAtLogin) != null) {
                yield helper.setToGlobal(OPEN_AT_LOGIN_KEY, legacyGlobal.openAtLogin);
                updatedGlobal = true;
                delete legacyGlobal.openAtLogin;
            }
            if ((legacyGlobal === null || legacyGlobal === void 0 ? void 0 : legacyGlobal.alwaysShowDock) != null) {
                yield helper.setToGlobal(ALWAYS_SHOW_DOCK_KEY, legacyGlobal.alwaysShowDock);
                updatedGlobal = true;
                delete legacyGlobal.alwaysShowDock;
            }
            if ((legacyGlobal === null || legacyGlobal === void 0 ? void 0 : legacyGlobal.enableAlwaysOnTop) != null) {
                yield helper.setToGlobal(ALWAYS_ON_TOP_KEY, legacyGlobal.enableAlwaysOnTop);
                updatedGlobal = true;
                delete legacyGlobal.enableAlwaysOnTop;
            }
            if (updatedGlobal) {
                yield helper.set("global", legacyGlobal);
            }
            function migrateAccount(userId, account) {
                return _47_move_desktop_settings_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    // We only migrate the global setting for this, if we find it on the account object
                    // just delete it.
                    if (((_a = account === null || account === void 0 ? void 0 : account.settings) === null || _a === void 0 ? void 0 : _a.enableAlwaysOnTop) != null) {
                        delete account.settings.enableAlwaysOnTop;
                        yield helper.set(userId, account);
                    }
                });
            }
            const accounts = yield helper.getAccounts();
            yield Promise.all(accounts.map(({ userId, account }) => migrateAccount(userId, account)));
        });
    }
    rollback(helper) {
        throw IRREVERSIBLE;
    }
}

;// ../../libs/state/src/state-migrations/migrations/48-move-ddg-to-state-provider.ts
var _48_move_ddg_to_state_provider_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const DDG_KEY = {
    key: "enableDuckDuckGoBrowserIntegration",
    stateDefinition: {
        name: "autofillSettings",
    },
};
class MoveDdgToStateProviderMigrator extends Migrator {
    migrate(helper) {
        return _48_move_ddg_to_state_provider_awaiter(this, void 0, void 0, function* () {
            // global state
            const global = yield helper.get("global");
            if ((global === null || global === void 0 ? void 0 : global.enableDuckDuckGoBrowserIntegration) == null) {
                return;
            }
            yield helper.setToGlobal(DDG_KEY, global.enableDuckDuckGoBrowserIntegration);
            delete global.enableDuckDuckGoBrowserIntegration;
            yield helper.set("global", global);
        });
    }
    rollback(helper) {
        return _48_move_ddg_to_state_provider_awaiter(this, void 0, void 0, function* () {
            var _a;
            const enableDdg = yield helper.getFromGlobal(DDG_KEY);
            if (!enableDdg) {
                return;
            }
            const global = (_a = (yield helper.get("global"))) !== null && _a !== void 0 ? _a : {};
            global.enableDuckDuckGoBrowserIntegration = enableDdg;
            yield helper.set("global", global);
            yield helper.removeFromGlobal(DDG_KEY);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/49-move-account-server-configs.ts
var _49_move_account_server_configs_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const _49_move_account_server_configs_CONFIG_DISK = { name: "config" };
const USER_SERVER_CONFIG = {
    stateDefinition: _49_move_account_server_configs_CONFIG_DISK,
    key: "serverConfig",
};
class AccountServerConfigMigrator extends Migrator {
    migrate(helper) {
        return _49_move_account_server_configs_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _49_move_account_server_configs_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    if (((_a = account === null || account === void 0 ? void 0 : account.settings) === null || _a === void 0 ? void 0 : _a.serverConfig) != null) {
                        yield helper.setToUser(userId, USER_SERVER_CONFIG, account.settings.serverConfig);
                        delete account.settings.serverConfig;
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
    rollback(helper) {
        return _49_move_account_server_configs_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function rollbackAccount(userId, account) {
                return _49_move_account_server_configs_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const serverConfig = yield helper.getFromUser(userId, USER_SERVER_CONFIG);
                    if (serverConfig) {
                        account !== null && account !== void 0 ? account : (account = {});
                        (_a = account.settings) !== null && _a !== void 0 ? _a : (account.settings = {});
                        account.settings.serverConfig = serverConfig;
                        yield helper.setToUser(userId, USER_SERVER_CONFIG, null);
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/5-add-key-type-to-org-keys.ts
var _5_add_key_type_to_org_keys_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

class AddKeyTypeToOrgKeysMigrator extends Migrator {
    migrate(helper) {
        return _5_add_key_type_to_org_keys_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function updateOrgKey(userId, account) {
                return _5_add_key_type_to_org_keys_awaiter(this, void 0, void 0, function* () {
                    var _a, _b;
                    const encryptedOrgKeys = (_b = (_a = account === null || account === void 0 ? void 0 : account.keys) === null || _a === void 0 ? void 0 : _a.organizationKeys) === null || _b === void 0 ? void 0 : _b.encrypted;
                    if (encryptedOrgKeys == null) {
                        return;
                    }
                    const newOrgKeys = {};
                    Object.entries(encryptedOrgKeys).forEach(([orgId, encKey]) => {
                        newOrgKeys[orgId] = {
                            type: "organization",
                            key: encKey,
                        };
                    });
                    account.keys.organizationKeys.encrypted = newOrgKeys;
                    yield helper.set(userId, account);
                });
            }
            // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
            // eslint-disable-next-line @typescript-eslint/no-floating-promises
            Promise.all(accounts.map(({ userId, account }) => updateOrgKey(userId, account)));
        });
    }
    rollback(helper) {
        return _5_add_key_type_to_org_keys_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function updateOrgKey(userId, account) {
                return _5_add_key_type_to_org_keys_awaiter(this, void 0, void 0, function* () {
                    var _a, _b;
                    const encryptedOrgKeys = (_b = (_a = account === null || account === void 0 ? void 0 : account.keys) === null || _a === void 0 ? void 0 : _a.organizationKeys) === null || _b === void 0 ? void 0 : _b.encrypted;
                    if (encryptedOrgKeys == null) {
                        return;
                    }
                    const newOrgKeys = {};
                    Object.entries(encryptedOrgKeys).forEach(([orgId, encKey]) => {
                        newOrgKeys[orgId] = encKey.key;
                    });
                    account.keys.organizationKeys.encrypted = newOrgKeys;
                    yield helper.set(userId, account);
                });
            }
            // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
            // eslint-disable-next-line @typescript-eslint/no-floating-promises
            Promise.all(accounts.map((_a) => _5_add_key_type_to_org_keys_awaiter(this, [_a], void 0, function* ({ userId, account }) { return updateOrgKey(userId, account); })));
        });
    }
    // Override is necessary because default implementation assumes `stateVersion` at the root, but for this version
    // it is nested inside a global object.
    updateVersion(helper, direction) {
        return _5_add_key_type_to_org_keys_awaiter(this, void 0, void 0, function* () {
            const endVersion = direction === "up" ? this.toVersion : this.fromVersion;
            helper.currentVersion = endVersion;
            const global = (yield helper.get("global")) || {};
            yield helper.set("global", Object.assign(Object.assign({}, global), { stateVersion: endVersion }));
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/50-move-key-connector-to-state-provider.ts
var _50_move_key_connector_to_state_provider_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const usesKeyConnectorKeyDefinition = {
    key: "usesKeyConnector",
    stateDefinition: {
        name: "keyConnector",
    },
};
const convertAccountToKeyConnectorKeyDefinition = {
    key: "convertAccountToKeyConnector",
    stateDefinition: {
        name: "keyConnector",
    },
};
class KeyConnectorMigrator extends Migrator {
    migrate(helper) {
        return _50_move_key_connector_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _50_move_key_connector_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    var _a, _b;
                    const usesKeyConnector = (_a = account === null || account === void 0 ? void 0 : account.profile) === null || _a === void 0 ? void 0 : _a.usesKeyConnector;
                    const convertAccountToKeyConnector = (_b = account === null || account === void 0 ? void 0 : account.profile) === null || _b === void 0 ? void 0 : _b.convertAccountToKeyConnector;
                    if (usesKeyConnector == null && convertAccountToKeyConnector == null) {
                        return;
                    }
                    if (usesKeyConnector != null) {
                        yield helper.setToUser(userId, usesKeyConnectorKeyDefinition, usesKeyConnector);
                        delete account.profile.usesKeyConnector;
                    }
                    if (convertAccountToKeyConnector != null) {
                        yield helper.setToUser(userId, convertAccountToKeyConnectorKeyDefinition, convertAccountToKeyConnector);
                        delete account.profile.convertAccountToKeyConnector;
                    }
                    yield helper.set(userId, account);
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
    rollback(helper) {
        return _50_move_key_connector_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function rollbackAccount(userId, account) {
                return _50_move_key_connector_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    const usesKeyConnector = yield helper.getFromUser(userId, usesKeyConnectorKeyDefinition);
                    const convertAccountToKeyConnector = yield helper.getFromUser(userId, convertAccountToKeyConnectorKeyDefinition);
                    if (usesKeyConnector == null && convertAccountToKeyConnector == null) {
                        return;
                    }
                    if (usesKeyConnector != null) {
                        account.profile.usesKeyConnector = usesKeyConnector;
                        yield helper.setToUser(userId, usesKeyConnectorKeyDefinition, null);
                    }
                    if (convertAccountToKeyConnector != null) {
                        account.profile.convertAccountToKeyConnector = convertAccountToKeyConnector;
                        yield helper.setToUser(userId, convertAccountToKeyConnectorKeyDefinition, null);
                    }
                    yield helper.set(userId, account);
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/51-move-remembered-email-to-state-providers.ts
var _51_move_remembered_email_to_state_providers_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const LOGIN_EMAIL_STATE = { name: "loginEmail" };
const STORED_EMAIL = {
    key: "storedEmail",
    stateDefinition: LOGIN_EMAIL_STATE,
};
class RememberedEmailMigrator extends Migrator {
    migrate(helper) {
        return _51_move_remembered_email_to_state_providers_awaiter(this, void 0, void 0, function* () {
            const legacyGlobal = yield helper.get("global");
            // Move global data
            if ((legacyGlobal === null || legacyGlobal === void 0 ? void 0 : legacyGlobal.rememberedEmail) != null) {
                yield helper.setToGlobal(STORED_EMAIL, legacyGlobal.rememberedEmail);
            }
            // Delete legacy global data
            legacyGlobal === null || legacyGlobal === void 0 ? true : delete legacyGlobal.rememberedEmail;
            yield helper.set("global", legacyGlobal);
        });
    }
    rollback(helper) {
        return _51_move_remembered_email_to_state_providers_awaiter(this, void 0, void 0, function* () {
            let legacyGlobal = yield helper.get("global");
            let updatedLegacyGlobal = false;
            const globalStoredEmail = yield helper.getFromGlobal(STORED_EMAIL);
            if (globalStoredEmail) {
                if (!legacyGlobal) {
                    legacyGlobal = {};
                }
                updatedLegacyGlobal = true;
                legacyGlobal.rememberedEmail = globalStoredEmail;
                yield helper.setToGlobal(STORED_EMAIL, null);
            }
            if (updatedLegacyGlobal) {
                yield helper.set("global", legacyGlobal);
            }
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/52-delete-installed-version.ts
var _52_delete_installed_version_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

class DeleteInstalledVersion extends Migrator {
    migrate(helper) {
        return _52_delete_installed_version_awaiter(this, void 0, void 0, function* () {
            const legacyGlobal = yield helper.get("global");
            if ((legacyGlobal === null || legacyGlobal === void 0 ? void 0 : legacyGlobal.installedVersion) != null) {
                delete legacyGlobal.installedVersion;
                yield helper.set("global", legacyGlobal);
            }
        });
    }
    rollback(helper) {
        throw IRREVERSIBLE;
    }
}

;// ../../libs/state/src/state-migrations/migrations/53-migrate-device-trust-svc-to-state-providers.ts
var _53_migrate_device_trust_svc_to_state_providers_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const DEVICE_KEY = {
    key: "deviceKey", // matches KeyDefinition.key in DeviceTrustService
    stateDefinition: {
        name: "deviceTrust", // matches StateDefinition.name in StateDefinitions
    },
};
const SHOULD_TRUST_DEVICE = {
    key: "shouldTrustDevice",
    stateDefinition: {
        name: "deviceTrust",
    },
};
class DeviceTrustServiceStateProviderMigrator extends Migrator {
    migrate(helper) {
        return _53_migrate_device_trust_svc_to_state_providers_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _53_migrate_device_trust_svc_to_state_providers_awaiter(this, void 0, void 0, function* () {
                    var _a, _b;
                    let updatedAccount = false;
                    // Migrate deviceKey
                    const existingDeviceKey = (_a = account === null || account === void 0 ? void 0 : account.keys) === null || _a === void 0 ? void 0 : _a.deviceKey;
                    if (existingDeviceKey != null) {
                        // Only migrate data that exists
                        yield helper.setToUser(userId, DEVICE_KEY, existingDeviceKey);
                        delete account.keys.deviceKey;
                        updatedAccount = true;
                    }
                    // Migrate shouldTrustDevice
                    const existingShouldTrustDevice = (_b = account === null || account === void 0 ? void 0 : account.settings) === null || _b === void 0 ? void 0 : _b.trustDeviceChoiceForDecryption;
                    if (existingShouldTrustDevice != null) {
                        yield helper.setToUser(userId, SHOULD_TRUST_DEVICE, existingShouldTrustDevice);
                        delete account.settings.trustDeviceChoiceForDecryption;
                        updatedAccount = true;
                    }
                    if (updatedAccount) {
                        // Save the migrated account
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
    rollback(helper) {
        return _53_migrate_device_trust_svc_to_state_providers_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function rollbackAccount(userId, account) {
                return _53_migrate_device_trust_svc_to_state_providers_awaiter(this, void 0, void 0, function* () {
                    // Rollback deviceKey
                    const migratedDeviceKey = yield helper.getFromUser(userId, DEVICE_KEY);
                    if ((account === null || account === void 0 ? void 0 : account.keys) && migratedDeviceKey != null) {
                        account.keys.deviceKey = migratedDeviceKey;
                        yield helper.set(userId, account);
                    }
                    yield helper.setToUser(userId, DEVICE_KEY, null);
                    // Rollback shouldTrustDevice
                    const migratedShouldTrustDevice = yield helper.getFromUser(userId, SHOULD_TRUST_DEVICE);
                    if ((account === null || account === void 0 ? void 0 : account.settings) && migratedShouldTrustDevice != null) {
                        account.settings.trustDeviceChoiceForDecryption = migratedShouldTrustDevice;
                        yield helper.set(userId, account);
                    }
                    yield helper.setToUser(userId, SHOULD_TRUST_DEVICE, null);
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/54-move-encrypted-sends.ts
var _54_move_encrypted_sends_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var SendType;
(function (SendType) {
    SendType[SendType["Text"] = 0] = "Text";
    SendType[SendType["File"] = 1] = "File";
})(SendType || (SendType = {}));
const ENCRYPTED_SENDS = {
    stateDefinition: {
        name: "send",
    },
    key: "sends",
};
/**
 * Only encrypted sends are stored on disk. Only the encrypted items need to be
 * migrated from the previous sends state data.
 */
class SendMigrator extends Migrator {
    migrate(helper) {
        return _54_move_encrypted_sends_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _54_move_encrypted_sends_awaiter(this, void 0, void 0, function* () {
                    var _a, _b;
                    const value = (_b = (_a = account === null || account === void 0 ? void 0 : account.data) === null || _a === void 0 ? void 0 : _a.sends) === null || _b === void 0 ? void 0 : _b.encrypted;
                    if (value != null) {
                        yield helper.setToUser(userId, ENCRYPTED_SENDS, value);
                        delete account.data.sends;
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
    rollback(helper) {
        return _54_move_encrypted_sends_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function rollbackAccount(userId, account) {
                return _54_move_encrypted_sends_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const value = yield helper.getFromUser(userId, ENCRYPTED_SENDS);
                    if (account) {
                        account.data = Object.assign((_a = account.data) !== null && _a !== void 0 ? _a : {}, {
                            sends: {
                                encrypted: value,
                            },
                        });
                        yield helper.set(userId, account);
                    }
                    yield helper.setToUser(userId, ENCRYPTED_SENDS, null);
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/55-move-master-key-state-to-provider.ts
var _55_move_master_key_state_to_provider_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const FORCE_SET_PASSWORD_REASON_DEFINITION = {
    key: "forceSetPasswordReason",
    stateDefinition: {
        name: "masterPassword",
    },
};
const MASTER_KEY_HASH_DEFINITION = {
    key: "masterKeyHash",
    stateDefinition: {
        name: "masterPassword",
    },
};
const MASTER_KEY_ENCRYPTED_USER_KEY_DEFINITION = {
    key: "masterKeyEncryptedUserKey",
    stateDefinition: {
        name: "masterPassword",
    },
};
class MoveMasterKeyStateToProviderMigrator extends Migrator {
    migrate(helper) {
        return _55_move_master_key_state_to_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _55_move_master_key_state_to_provider_awaiter(this, void 0, void 0, function* () {
                    var _a, _b, _c;
                    const forceSetPasswordReason = (_a = account === null || account === void 0 ? void 0 : account.profile) === null || _a === void 0 ? void 0 : _a.forceSetPasswordReason;
                    if (forceSetPasswordReason != null) {
                        yield helper.setToUser(userId, FORCE_SET_PASSWORD_REASON_DEFINITION, forceSetPasswordReason);
                        delete account.profile.forceSetPasswordReason;
                        yield helper.set(userId, account);
                    }
                    const masterKeyHash = (_b = account === null || account === void 0 ? void 0 : account.profile) === null || _b === void 0 ? void 0 : _b.keyHash;
                    if (masterKeyHash != null) {
                        yield helper.setToUser(userId, MASTER_KEY_HASH_DEFINITION, masterKeyHash);
                        delete account.profile.keyHash;
                        yield helper.set(userId, account);
                    }
                    const masterKeyEncryptedUserKey = (_c = account === null || account === void 0 ? void 0 : account.keys) === null || _c === void 0 ? void 0 : _c.masterKeyEncryptedUserKey;
                    if (masterKeyEncryptedUserKey != null) {
                        yield helper.setToUser(userId, MASTER_KEY_ENCRYPTED_USER_KEY_DEFINITION, masterKeyEncryptedUserKey);
                        delete account.keys.masterKeyEncryptedUserKey;
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
    rollback(helper) {
        return _55_move_master_key_state_to_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function rollbackAccount(userId, account) {
                return _55_move_master_key_state_to_provider_awaiter(this, void 0, void 0, function* () {
                    var _a, _b, _c;
                    const forceSetPasswordReason = yield helper.getFromUser(userId, FORCE_SET_PASSWORD_REASON_DEFINITION);
                    const masterKeyHash = yield helper.getFromUser(userId, MASTER_KEY_HASH_DEFINITION);
                    const masterKeyEncryptedUserKey = yield helper.getFromUser(userId, MASTER_KEY_ENCRYPTED_USER_KEY_DEFINITION);
                    if (account != null) {
                        if (forceSetPasswordReason != null) {
                            account.profile = Object.assign((_a = account.profile) !== null && _a !== void 0 ? _a : {}, {
                                forceSetPasswordReason,
                            });
                        }
                        if (masterKeyHash != null) {
                            account.profile = Object.assign((_b = account.profile) !== null && _b !== void 0 ? _b : {}, {
                                keyHash: masterKeyHash,
                            });
                        }
                        if (masterKeyEncryptedUserKey != null) {
                            account.keys = Object.assign((_c = account.keys) !== null && _c !== void 0 ? _c : {}, {
                                masterKeyEncryptedUserKey,
                            });
                        }
                        yield helper.set(userId, account);
                    }
                    yield helper.setToUser(userId, FORCE_SET_PASSWORD_REASON_DEFINITION, null);
                    yield helper.setToUser(userId, MASTER_KEY_HASH_DEFINITION, null);
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/56-move-auth-requests.ts
var _56_move_auth_requests_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const ADMIN_AUTH_REQUEST_KEY = {
    stateDefinition: {
        name: "authRequestLocal",
    },
    key: "adminAuthRequest",
};
const ACCEPT_AUTH_REQUESTS_KEY = {
    stateDefinition: {
        name: "authRequestLocal",
    },
    key: "acceptAuthRequests",
};
class AuthRequestMigrator extends Migrator {
    migrate(helper) {
        return _56_move_auth_requests_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _56_move_auth_requests_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    let updatedAccount = false;
                    // Migrate admin auth request
                    const existingAdminAuthRequest = account === null || account === void 0 ? void 0 : account.adminAuthRequest;
                    if (existingAdminAuthRequest != null) {
                        yield helper.setToUser(userId, ADMIN_AUTH_REQUEST_KEY, existingAdminAuthRequest);
                        delete account.adminAuthRequest;
                        updatedAccount = true;
                    }
                    // Migrate approve login requests
                    const existingApproveLoginRequests = (_a = account === null || account === void 0 ? void 0 : account.settings) === null || _a === void 0 ? void 0 : _a.approveLoginRequests;
                    if (existingApproveLoginRequests != null) {
                        yield helper.setToUser(userId, ACCEPT_AUTH_REQUESTS_KEY, existingApproveLoginRequests);
                        delete account.settings.approveLoginRequests;
                        updatedAccount = true;
                    }
                    if (updatedAccount) {
                        // Save the migrated account
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
    rollback(helper) {
        return _56_move_auth_requests_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function rollbackAccount(userId, account) {
                return _56_move_auth_requests_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    let updatedAccount = false;
                    // Rollback admin auth request
                    const migratedAdminAuthRequest = yield helper.getFromUser(userId, ADMIN_AUTH_REQUEST_KEY);
                    if (migratedAdminAuthRequest != null) {
                        account.adminAuthRequest = migratedAdminAuthRequest;
                        updatedAccount = true;
                    }
                    yield helper.setToUser(userId, ADMIN_AUTH_REQUEST_KEY, null);
                    // Rollback approve login requests
                    const migratedAcceptAuthRequest = yield helper.getFromUser(userId, ACCEPT_AUTH_REQUESTS_KEY);
                    if (migratedAcceptAuthRequest != null) {
                        account.settings = Object.assign((_a = account.settings) !== null && _a !== void 0 ? _a : {}, {
                            approveLoginRequests: migratedAcceptAuthRequest,
                        });
                        updatedAccount = true;
                    }
                    yield helper.setToUser(userId, ACCEPT_AUTH_REQUESTS_KEY, null);
                    if (updatedAccount) {
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/57-move-cipher-service-to-state-provider.ts
var _57_move_cipher_service_to_state_provider_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const _57_move_cipher_service_to_state_provider_CIPHERS_DISK_LOCAL = {
    key: "localData",
    stateDefinition: {
        name: "ciphersLocal",
    },
};
const _57_move_cipher_service_to_state_provider_CIPHERS_DISK = {
    key: "ciphers",
    stateDefinition: {
        name: "ciphers",
    },
};
class CipherServiceMigrator extends Migrator {
    migrate(helper) {
        return _57_move_cipher_service_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _57_move_cipher_service_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    var _a, _b, _c;
                    let updatedAccount = false;
                    //Migrate localData
                    const localData = (_a = account === null || account === void 0 ? void 0 : account.data) === null || _a === void 0 ? void 0 : _a.localData;
                    if (localData != null) {
                        yield helper.setToUser(userId, _57_move_cipher_service_to_state_provider_CIPHERS_DISK_LOCAL, localData);
                        delete account.data.localData;
                        updatedAccount = true;
                    }
                    //Migrate ciphers
                    const ciphers = (_c = (_b = account === null || account === void 0 ? void 0 : account.data) === null || _b === void 0 ? void 0 : _b.ciphers) === null || _c === void 0 ? void 0 : _c.encrypted;
                    if (ciphers != null) {
                        yield helper.setToUser(userId, _57_move_cipher_service_to_state_provider_CIPHERS_DISK, ciphers);
                        delete account.data.ciphers;
                        updatedAccount = true;
                    }
                    if (updatedAccount) {
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
    rollback(helper) {
        return _57_move_cipher_service_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function rollbackAccount(userId, account) {
                return _57_move_cipher_service_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    //rollback localData
                    const localData = yield helper.getFromUser(userId, _57_move_cipher_service_to_state_provider_CIPHERS_DISK_LOCAL);
                    if (account.data && localData != null) {
                        account.data.localData = localData;
                        yield helper.set(userId, account);
                    }
                    yield helper.setToUser(userId, _57_move_cipher_service_to_state_provider_CIPHERS_DISK_LOCAL, null);
                    //rollback ciphers
                    const ciphers = yield helper.getFromUser(userId, _57_move_cipher_service_to_state_provider_CIPHERS_DISK);
                    if (account.data && ciphers != null) {
                        (_a = account.data).ciphers || (_a.ciphers = { encrypted: null });
                        account.data.ciphers.encrypted = ciphers;
                        yield helper.set(userId, account);
                    }
                    yield helper.setToUser(userId, _57_move_cipher_service_to_state_provider_CIPHERS_DISK, null);
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/58-remove-refresh-token-migrated-state-provider-flag.ts
var _58_remove_refresh_token_migrated_state_provider_flag_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const REFRESH_TOKEN_MIGRATED_TO_SECURE_STORAGE = {
    key: "refreshTokenMigratedToSecureStorage", // matches KeyDefinition.key
    stateDefinition: {
        name: "token", // matches StateDefinition.name in StateDefinitions
    },
};
class RemoveRefreshTokenMigratedFlagMigrator extends Migrator {
    migrate(helper) {
        return _58_remove_refresh_token_migrated_state_provider_flag_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _58_remove_refresh_token_migrated_state_provider_flag_awaiter(this, void 0, void 0, function* () {
                    const refreshTokenMigratedFlag = yield helper.getFromUser(userId, REFRESH_TOKEN_MIGRATED_TO_SECURE_STORAGE);
                    if (refreshTokenMigratedFlag != null) {
                        // Only delete the flag if it exists
                        yield helper.removeFromUser(userId, REFRESH_TOKEN_MIGRATED_TO_SECURE_STORAGE);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
    rollback(helper) {
        return _58_remove_refresh_token_migrated_state_provider_flag_awaiter(this, void 0, void 0, function* () {
            throw IRREVERSIBLE;
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/59-move-kdf-config-to-state-provider.ts
var _59_move_kdf_config_to_state_provider_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var KdfType;
(function (KdfType) {
    KdfType[KdfType["PBKDF2_SHA256"] = 0] = "PBKDF2_SHA256";
    KdfType[KdfType["Argon2id"] = 1] = "Argon2id";
})(KdfType || (KdfType = {}));
class KdfConfig {
}
const kdfConfigKeyDefinition = {
    key: "kdfConfig",
    stateDefinition: {
        name: "kdfConfig",
    },
};
class KdfConfigMigrator extends Migrator {
    migrate(helper) {
        return _59_move_kdf_config_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _59_move_kdf_config_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    var _a, _b, _c, _d, _e, _f, _g, _h;
                    const iterations = (_a = account === null || account === void 0 ? void 0 : account.profile) === null || _a === void 0 ? void 0 : _a.kdfIterations;
                    const kdfType = (_b = account === null || account === void 0 ? void 0 : account.profile) === null || _b === void 0 ? void 0 : _b.kdfType;
                    const memory = (_c = account === null || account === void 0 ? void 0 : account.profile) === null || _c === void 0 ? void 0 : _c.kdfMemory;
                    const parallelism = (_d = account === null || account === void 0 ? void 0 : account.profile) === null || _d === void 0 ? void 0 : _d.kdfParallelism;
                    const kdfConfig = {
                        iterations: iterations,
                        kdfType: kdfType,
                        memory: memory,
                        parallelism: parallelism,
                    };
                    if (kdfConfig != null) {
                        yield helper.setToUser(userId, kdfConfigKeyDefinition, kdfConfig);
                        (_e = account === null || account === void 0 ? void 0 : account.profile) === null || _e === void 0 ? true : delete _e.kdfIterations;
                        (_f = account === null || account === void 0 ? void 0 : account.profile) === null || _f === void 0 ? true : delete _f.kdfType;
                        (_g = account === null || account === void 0 ? void 0 : account.profile) === null || _g === void 0 ? true : delete _g.kdfMemory;
                        (_h = account === null || account === void 0 ? void 0 : account.profile) === null || _h === void 0 ? true : delete _h.kdfParallelism;
                    }
                    yield helper.set(userId, account);
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
    rollback(helper) {
        return _59_move_kdf_config_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function rollbackAccount(userId, account) {
                return _59_move_kdf_config_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    const kdfConfig = yield helper.getFromUser(userId, kdfConfigKeyDefinition);
                    if (kdfConfig != null) {
                        account.profile.kdfIterations = kdfConfig.iterations;
                        account.profile.kdfType = kdfConfig.kdfType;
                        account.profile.kdfMemory = kdfConfig.memory;
                        account.profile.kdfParallelism = kdfConfig.parallelism;
                        yield helper.setToUser(userId, kdfConfigKeyDefinition, null);
                    }
                    yield helper.set(userId, account);
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/6-remove-legacy-etm-key.ts
var _6_remove_legacy_etm_key_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

class RemoveLegacyEtmKeyMigrator extends Migrator {
    migrate(helper) {
        return _6_remove_legacy_etm_key_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function updateAccount(userId, account) {
                return _6_remove_legacy_etm_key_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    if ((_a = account === null || account === void 0 ? void 0 : account.keys) === null || _a === void 0 ? void 0 : _a.legacyEtmKey) {
                        delete account.keys.legacyEtmKey;
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all(accounts.map(({ userId, account }) => updateAccount(userId, account)));
        });
    }
    rollback(helper) {
        return _6_remove_legacy_etm_key_awaiter(this, void 0, void 0, function* () {
            throw IRREVERSIBLE;
        });
    }
    // Override is necessary because default implementation assumes `stateVersion` at the root, but for this version
    // it is nested inside a global object.
    updateVersion(helper, direction) {
        return _6_remove_legacy_etm_key_awaiter(this, void 0, void 0, function* () {
            const endVersion = direction === "up" ? this.toVersion : this.fromVersion;
            helper.currentVersion = endVersion;
            const global = (yield helper.get("global")) || {};
            yield helper.set("global", Object.assign(Object.assign({}, global), { stateVersion: endVersion }));
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/60-known-accounts.ts
var _60_known_accounts_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const ACCOUNT_ACCOUNTS = {
    stateDefinition: {
        name: "account",
    },
    key: "accounts",
};
const ACCOUNT_ACTIVE_ACCOUNT_ID = {
    stateDefinition: {
        name: "account",
    },
    key: "activeAccountId",
};
const ACCOUNT_ACTIVITY = {
    stateDefinition: {
        name: "account",
    },
    key: "activity",
};
class KnownAccountsMigrator extends Migrator {
    migrate(helper) {
        return _60_known_accounts_awaiter(this, void 0, void 0, function* () {
            yield this.migrateAuthenticatedAccounts(helper);
            yield this.migrateActiveAccountId(helper);
            yield this.migrateAccountActivity(helper);
        });
    }
    rollback(helper) {
        return _60_known_accounts_awaiter(this, void 0, void 0, function* () {
            var _a;
            // authenticated account are removed, but the accounts record also contains logged out accounts. Best we can do is to add them all back
            const userIds = (_a = (yield helper.getKnownUserIds())) !== null && _a !== void 0 ? _a : [];
            yield helper.set("authenticatedAccounts", userIds);
            yield helper.removeFromGlobal(ACCOUNT_ACCOUNTS);
            // Active Account Id
            const activeAccountId = yield helper.getFromGlobal(ACCOUNT_ACTIVE_ACCOUNT_ID);
            if (activeAccountId) {
                yield helper.set("activeUserId", activeAccountId);
            }
            yield helper.removeFromGlobal(ACCOUNT_ACTIVE_ACCOUNT_ID);
            // Account Activity
            const accountActivity = yield helper.getFromGlobal(ACCOUNT_ACTIVITY);
            if (accountActivity) {
                const toStore = Object.entries(accountActivity).reduce((agg, [userId, dateString]) => {
                    agg[userId] = new Date(dateString).getTime();
                    return agg;
                }, {});
                yield helper.set("accountActivity", toStore);
            }
            yield helper.removeFromGlobal(ACCOUNT_ACTIVITY);
        });
    }
    migrateAuthenticatedAccounts(helper) {
        return _60_known_accounts_awaiter(this, void 0, void 0, function* () {
            var _a;
            const authenticatedAccounts = (_a = (yield helper.get("authenticatedAccounts"))) !== null && _a !== void 0 ? _a : [];
            const accounts = yield Promise.all(authenticatedAccounts.map((userId) => _60_known_accounts_awaiter(this, void 0, void 0, function* () {
                const account = yield helper.get(userId);
                return { userId, account };
            })));
            const accountsToStore = accounts.reduce((agg, { userId, account }) => {
                var _a, _b;
                if (account === null || account === void 0 ? void 0 : account.profile) {
                    agg[userId] = {
                        email: (_a = account.profile.email) !== null && _a !== void 0 ? _a : "",
                        emailVerified: (_b = account.profile.emailVerified) !== null && _b !== void 0 ? _b : false,
                        name: account.profile.name,
                    };
                }
                return agg;
            }, {});
            yield helper.setToGlobal(ACCOUNT_ACCOUNTS, accountsToStore);
            yield helper.remove("authenticatedAccounts");
        });
    }
    migrateAccountActivity(helper) {
        return _60_known_accounts_awaiter(this, void 0, void 0, function* () {
            const stored = yield helper.get("accountActivity");
            const accountActivity = Object.entries(stored !== null && stored !== void 0 ? stored : {}).reduce((agg, [userId, dateMs]) => {
                agg[userId] = JSON.stringify(new Date(dateMs));
                return agg;
            }, {});
            yield helper.setToGlobal(ACCOUNT_ACTIVITY, accountActivity);
            yield helper.remove("accountActivity");
        });
    }
    migrateActiveAccountId(helper) {
        return _60_known_accounts_awaiter(this, void 0, void 0, function* () {
            const activeAccountId = yield helper.get("activeUserId");
            yield helper.setToGlobal(ACCOUNT_ACTIVE_ACCOUNT_ID, activeAccountId);
            yield helper.remove("activeUserId");
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/61-move-pin-state-to-providers.ts
var _61_move_pin_state_to_providers_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const PIN_STATE = { name: "pinUnlock" };
const PIN_KEY_ENCRYPTED_USER_KEY_PERSISTENT = {
    stateDefinition: PIN_STATE,
    key: "pinKeyEncryptedUserKeyPersistent",
};
const USER_KEY_ENCRYPTED_PIN = {
    stateDefinition: PIN_STATE,
    key: "userKeyEncryptedPin",
};
const OLD_PIN_KEY_ENCRYPTED_MASTER_KEY = {
    stateDefinition: PIN_STATE,
    key: "oldPinKeyEncryptedMasterKey",
};
class PinStateMigrator extends Migrator {
    migrate(helper) {
        return _61_move_pin_state_to_providers_awaiter(this, void 0, void 0, function* () {
            const legacyAccounts = yield helper.getAccounts();
            let updatedAccount = false;
            function migrateAccount(userId, account) {
                return _61_move_pin_state_to_providers_awaiter(this, void 0, void 0, function* () {
                    var _a, _b, _c, _d;
                    // Migrate pinKeyEncryptedUserKey (to `pinKeyEncryptedUserKeyPersistent`)
                    if (((_a = account === null || account === void 0 ? void 0 : account.settings) === null || _a === void 0 ? void 0 : _a.pinKeyEncryptedUserKey) != null) {
                        yield helper.setToUser(userId, PIN_KEY_ENCRYPTED_USER_KEY_PERSISTENT, account.settings.pinKeyEncryptedUserKey);
                        delete account.settings.pinKeyEncryptedUserKey;
                        updatedAccount = true;
                    }
                    // Migrate protectedPin (to `userKeyEncryptedPin`)
                    if (((_b = account === null || account === void 0 ? void 0 : account.settings) === null || _b === void 0 ? void 0 : _b.protectedPin) != null) {
                        yield helper.setToUser(userId, USER_KEY_ENCRYPTED_PIN, account.settings.protectedPin);
                        delete account.settings.protectedPin;
                        updatedAccount = true;
                    }
                    // Migrate pinProtected (to `oldPinKeyEncryptedMasterKey`)
                    if (((_d = (_c = account === null || account === void 0 ? void 0 : account.settings) === null || _c === void 0 ? void 0 : _c.pinProtected) === null || _d === void 0 ? void 0 : _d.encrypted) != null) {
                        yield helper.setToUser(userId, OLD_PIN_KEY_ENCRYPTED_MASTER_KEY, account.settings.pinProtected.encrypted);
                        delete account.settings.pinProtected;
                        updatedAccount = true;
                    }
                    if (updatedAccount) {
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all([
                ...legacyAccounts.map(({ userId, account }) => migrateAccount(userId, account)),
            ]);
        });
    }
    rollback(helper) {
        return _61_move_pin_state_to_providers_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function rollbackAccount(userId, account) {
                return _61_move_pin_state_to_providers_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    let updatedAccount = false;
                    const accountPinKeyEncryptedUserKeyPersistent = yield helper.getFromUser(userId, PIN_KEY_ENCRYPTED_USER_KEY_PERSISTENT);
                    const accountUserKeyEncryptedPin = yield helper.getFromUser(userId, USER_KEY_ENCRYPTED_PIN);
                    const accountOldPinKeyEncryptedMasterKey = yield helper.getFromUser(userId, OLD_PIN_KEY_ENCRYPTED_MASTER_KEY);
                    if (!account) {
                        account = {};
                    }
                    if (accountPinKeyEncryptedUserKeyPersistent != null) {
                        account.settings.pinKeyEncryptedUserKey = accountPinKeyEncryptedUserKeyPersistent;
                        yield helper.setToUser(userId, PIN_KEY_ENCRYPTED_USER_KEY_PERSISTENT, null);
                        updatedAccount = true;
                    }
                    if (accountUserKeyEncryptedPin != null) {
                        account.settings.protectedPin = accountUserKeyEncryptedPin;
                        yield helper.setToUser(userId, USER_KEY_ENCRYPTED_PIN, null);
                        updatedAccount = true;
                    }
                    if (accountOldPinKeyEncryptedMasterKey != null) {
                        account.settings = Object.assign((_a = account.settings) !== null && _a !== void 0 ? _a : {}, {
                            pinProtected: {
                                encrypted: accountOldPinKeyEncryptedMasterKey,
                            },
                        });
                        yield helper.setToUser(userId, OLD_PIN_KEY_ENCRYPTED_MASTER_KEY, null);
                        updatedAccount = true;
                    }
                    if (updatedAccount) {
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all(accounts.map(({ userId, account }) => rollbackAccount(userId, account)));
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/62-migrate-vault-timeout-settings-svc-to-state-provider.ts
var _62_migrate_vault_timeout_settings_svc_to_state_provider_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const VAULT_TIMEOUT_SETTINGS_STATE_DEF_LIKE = {
    name: "vaultTimeoutSettings",
};
const VAULT_TIMEOUT = {
    key: "vaultTimeout", // matches KeyDefinition.key
    stateDefinition: VAULT_TIMEOUT_SETTINGS_STATE_DEF_LIKE,
};
const VAULT_TIMEOUT_ACTION = {
    key: "vaultTimeoutAction", // matches KeyDefinition.key
    stateDefinition: VAULT_TIMEOUT_SETTINGS_STATE_DEF_LIKE,
};
// Define mapping of old values to new values for migration purposes
const vaultTimeoutTypeMigrateRecord = {
    null: "never",
    "-1": "onRestart",
    "-2": "onLocked",
    "-3": "onSleep",
    "-4": "onIdle",
};
// define mapping of new values to old values for rollback purposes
const vaultTimeoutTypeRollbackRecord = {
    never: null,
    onRestart: -1,
    onLocked: -2,
    onSleep: -3,
    onIdle: -4,
};
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var ClientType;
(function (ClientType) {
    ClientType["Web"] = "web";
    ClientType["Browser"] = "browser";
    ClientType["Desktop"] = "desktop";
    ClientType["Cli"] = "cli";
})(ClientType || (ClientType = {}));
class VaultTimeoutSettingsServiceStateProviderMigrator extends Migrator {
    migrate(helper) {
        return _62_migrate_vault_timeout_settings_svc_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const globalData = yield helper.get("global");
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _62_migrate_vault_timeout_settings_svc_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    var _a, _b, _c, _d;
                    let updatedAccount = false;
                    // Migrate vault timeout
                    let existingVaultTimeout = (_a = account === null || account === void 0 ? void 0 : account.settings) === null || _a === void 0 ? void 0 : _a.vaultTimeout;
                    if (helper.clientType === ClientType.Cli && existingVaultTimeout === undefined) {
                        // The CLI does not set a vault timeout by default so we need to set it to null
                        // so that the migration can migrate null to "never" as the CLI does not have a vault timeout.
                        existingVaultTimeout = null;
                    }
                    if (existingVaultTimeout !== undefined) {
                        // check undefined so that we allow null values (previously meant never timeout)
                        // Only migrate data that exists
                        if (existingVaultTimeout === null || existingVaultTimeout < 0) {
                            // Map null or negative values to new string values
                            const newVaultTimeout = vaultTimeoutTypeMigrateRecord[existingVaultTimeout];
                            yield helper.setToUser(userId, VAULT_TIMEOUT, newVaultTimeout);
                        }
                        else {
                            // Persist positive numbers as is
                            yield helper.setToUser(userId, VAULT_TIMEOUT, existingVaultTimeout);
                        }
                        (_b = account === null || account === void 0 ? void 0 : account.settings) === null || _b === void 0 ? true : delete _b.vaultTimeout;
                        updatedAccount = true;
                    }
                    // Migrate vault timeout action
                    const existingVaultTimeoutAction = (_c = account === null || account === void 0 ? void 0 : account.settings) === null || _c === void 0 ? void 0 : _c.vaultTimeoutAction;
                    if (existingVaultTimeoutAction != null) {
                        // Only migrate data that exists
                        yield helper.setToUser(userId, VAULT_TIMEOUT_ACTION, existingVaultTimeoutAction);
                        (_d = account === null || account === void 0 ? void 0 : account.settings) === null || _d === void 0 ? true : delete _d.vaultTimeoutAction;
                        updatedAccount = true;
                    }
                    // Note: we are explicitly not worrying about mapping over the global fallback vault timeout / action
                    // into the new state provider framework.  It was originally a fallback but hasn't been used for years
                    // so this migration will clean up the global properties fully.
                    if (updatedAccount) {
                        // Save the migrated account only if it was updated
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
            // Delete global data (works for browser extension and web; CLI doesn't have these as global settings).
            globalData === null || globalData === void 0 ? true : delete globalData.vaultTimeout;
            globalData === null || globalData === void 0 ? true : delete globalData.vaultTimeoutAction;
            yield helper.set("global", globalData);
            // Remove desktop only settings. These aren't found by the above global key removal b/c of
            // the different storage key format. This removal does not cause any issues on migrating for other clients.
            yield helper.remove("global\\.vaultTimeout");
            yield helper.remove("global\\.vaultTimeoutAction");
        });
    }
    rollback(helper) {
        return _62_migrate_vault_timeout_settings_svc_to_state_provider_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function rollbackAccount(userId, account) {
                return _62_migrate_vault_timeout_settings_svc_to_state_provider_awaiter(this, void 0, void 0, function* () {
                    let updatedLegacyAccount = false;
                    // Rollback vault timeout
                    const migratedVaultTimeout = yield helper.getFromUser(userId, VAULT_TIMEOUT);
                    if ((account === null || account === void 0 ? void 0 : account.settings) && migratedVaultTimeout != null) {
                        if (typeof migratedVaultTimeout === "string") {
                            // Map new string values back to old values
                            account.settings.vaultTimeout = vaultTimeoutTypeRollbackRecord[migratedVaultTimeout];
                        }
                        else {
                            // persist numbers as is
                            account.settings.vaultTimeout = migratedVaultTimeout;
                        }
                        updatedLegacyAccount = true;
                    }
                    yield helper.setToUser(userId, VAULT_TIMEOUT, null);
                    // Rollback vault timeout action
                    const migratedVaultTimeoutAction = yield helper.getFromUser(userId, VAULT_TIMEOUT_ACTION);
                    if ((account === null || account === void 0 ? void 0 : account.settings) && migratedVaultTimeoutAction != null) {
                        account.settings.vaultTimeoutAction = migratedVaultTimeoutAction;
                        updatedLegacyAccount = true;
                    }
                    yield helper.setToUser(userId, VAULT_TIMEOUT_ACTION, null);
                    if (updatedLegacyAccount) {
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/63-migrate-password-settings.ts
var _63_migrate_password_settings_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const NAVIGATION = {
    stateDefinition: {
        name: "generator",
    },
    key: "generatorSettings",
};
const PASSWORD = {
    stateDefinition: {
        name: "generator",
    },
    key: "passwordGeneratorSettings",
};
const PASSPHRASE = {
    stateDefinition: {
        name: "generator",
    },
    key: "passphraseGeneratorSettings",
};
class PasswordOptionsMigrator extends Migrator {
    migrate(helper) {
        return _63_migrate_password_settings_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _63_migrate_password_settings_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const legacyOptions = (_a = account === null || account === void 0 ? void 0 : account.settings) === null || _a === void 0 ? void 0 : _a.passwordGenerationOptions;
                    if (legacyOptions) {
                        const converted = convertSettings(legacyOptions);
                        yield storeSettings(helper, userId, converted);
                        yield deleteSettings(helper, userId, account);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
    rollback(helper) {
        return _63_migrate_password_settings_awaiter(this, void 0, void 0, function* () {
            // not supported
        });
    }
}
function convertSettings(options) {
    const password = {
        length: options.length,
        ambiguous: options.ambiguous,
        uppercase: options.uppercase,
        minUppercase: options.minUppercase,
        lowercase: options.lowercase,
        minLowercase: options.minLowercase,
        number: options.number,
        minNumber: options.minNumber,
        special: options.special,
        minSpecial: options.minSpecial,
    };
    const generator = {
        type: options.type,
    };
    const passphrase = {
        numWords: options.numWords,
        wordSeparator: options.wordSeparator,
        capitalize: options.capitalize,
        includeNumber: options.includeNumber,
    };
    return { generator, password, passphrase };
}
function storeSettings(helper, userId, converted) {
    return _63_migrate_password_settings_awaiter(this, void 0, void 0, function* () {
        var _a;
        const existing = (_a = (yield helper.getFromUser(userId, NAVIGATION))) !== null && _a !== void 0 ? _a : {};
        const updated = Object.assign(existing, converted.generator);
        yield Promise.all([
            helper.setToUser(userId, NAVIGATION, updated),
            helper.setToUser(userId, PASSPHRASE, converted.passphrase),
            helper.setToUser(userId, PASSWORD, converted.password),
        ]);
    });
}
function deleteSettings(helper, userId, account) {
    return _63_migrate_password_settings_awaiter(this, void 0, void 0, function* () {
        var _a;
        (_a = account === null || account === void 0 ? void 0 : account.settings) === null || _a === void 0 ? true : delete _a.passwordGenerationOptions;
        yield helper.set(userId, account);
    });
}

;// ../../libs/state/src/state-migrations/migrations/64-migrate-generator-history.ts
var _64_migrate_generator_history_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const HISTORY = {
    stateDefinition: {
        name: "generator",
    },
    key: "localGeneratorHistoryBuffer",
};
class GeneratorHistoryMigrator extends Migrator {
    migrate(helper) {
        return _64_migrate_generator_history_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _64_migrate_generator_history_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const data = (_a = account === null || account === void 0 ? void 0 : account.data) === null || _a === void 0 ? void 0 : _a.passwordGenerationHistory;
                    if (data && data.encrypted) {
                        yield helper.setToUser(userId, HISTORY, data.encrypted);
                        delete account.data.passwordGenerationHistory;
                        yield helper.set(userId, account);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
    rollback(helper) {
        return _64_migrate_generator_history_awaiter(this, void 0, void 0, function* () {
            // not supported
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/65-migrate-forwarder-settings.ts
var _65_migrate_forwarder_settings_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const _65_migrate_forwarder_settings_NAVIGATION = {
    stateDefinition: {
        name: "generator",
    },
    key: "generatorSettings",
};
const CATCHALL = {
    stateDefinition: {
        name: "generator",
    },
    key: "catchallGeneratorSettings",
};
const EFF_USERNAME = {
    stateDefinition: {
        name: "generator",
    },
    key: "effUsernameGeneratorSettings",
};
const SUBADDRESS = {
    stateDefinition: {
        name: "generator",
    },
    key: "subaddressGeneratorSettings",
};
const ADDY_IO = {
    stateDefinition: {
        name: "generator",
    },
    key: "addyIoBuffer",
};
const DUCK_DUCK_GO = {
    stateDefinition: {
        name: "generator",
    },
    key: "duckDuckGoBuffer",
};
const FASTMAIL = {
    stateDefinition: {
        name: "generator",
    },
    key: "fastmailBuffer",
};
const FIREFOX_RELAY = {
    stateDefinition: {
        name: "generator",
    },
    key: "firefoxRelayBuffer",
};
const FORWARD_EMAIL = {
    stateDefinition: {
        name: "generator",
    },
    key: "forwardEmailBuffer",
};
const SIMPLE_LOGIN = {
    stateDefinition: {
        name: "generator",
    },
    key: "simpleLoginBuffer",
};
class ForwarderOptionsMigrator extends Migrator {
    migrate(helper) {
        return _65_migrate_forwarder_settings_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _65_migrate_forwarder_settings_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const legacyOptions = (_a = account === null || account === void 0 ? void 0 : account.settings) === null || _a === void 0 ? void 0 : _a.usernameGenerationOptions;
                    if (legacyOptions) {
                        const converted = _65_migrate_forwarder_settings_convertSettings(legacyOptions);
                        yield _65_migrate_forwarder_settings_storeSettings(helper, userId, converted);
                        yield _65_migrate_forwarder_settings_deleteSettings(helper, userId, account);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
    rollback(helper) {
        return _65_migrate_forwarder_settings_awaiter(this, void 0, void 0, function* () {
            // not supported
        });
    }
}
function _65_migrate_forwarder_settings_convertSettings(options) {
    const forwarders = {
        addyIo: {
            baseUrl: options.forwardedAnonAddyBaseUrl,
            token: options.forwardedAnonAddyApiToken,
            domain: options.forwardedAnonAddyDomain,
        },
        duckDuckGo: {
            token: options.forwardedDuckDuckGoToken,
        },
        fastmail: {
            token: options.forwardedFastmailApiToken,
        },
        firefoxRelay: {
            token: options.forwardedFirefoxApiToken,
        },
        forwardEmail: {
            token: options.forwardedForwardEmailApiToken,
            domain: options.forwardedForwardEmailDomain,
        },
        simpleLogin: {
            token: options.forwardedSimpleLoginApiKey,
            baseUrl: options.forwardedSimpleLoginBaseUrl,
        },
    };
    const generator = {
        username: options.type,
        forwarder: options.forwardedService,
    };
    const algorithms = {
        effUsername: {
            wordCapitalize: options.wordCapitalize,
            wordIncludeNumber: options.wordIncludeNumber,
        },
        subaddress: {
            subaddressType: options.subaddressType,
            subaddressEmail: options.subaddressEmail,
        },
        catchall: {
            catchallType: options.catchallType,
            catchallDomain: options.catchallDomain,
        },
    };
    return { generator, algorithms, forwarders };
}
function _65_migrate_forwarder_settings_storeSettings(helper, userId, converted) {
    return _65_migrate_forwarder_settings_awaiter(this, void 0, void 0, function* () {
        yield Promise.all([
            helper.setToUser(userId, _65_migrate_forwarder_settings_NAVIGATION, converted.generator),
            helper.setToUser(userId, CATCHALL, converted.algorithms.catchall),
            helper.setToUser(userId, EFF_USERNAME, converted.algorithms.effUsername),
            helper.setToUser(userId, SUBADDRESS, converted.algorithms.subaddress),
            helper.setToUser(userId, ADDY_IO, converted.forwarders.addyIo),
            helper.setToUser(userId, DUCK_DUCK_GO, converted.forwarders.duckDuckGo),
            helper.setToUser(userId, FASTMAIL, converted.forwarders.fastmail),
            helper.setToUser(userId, FIREFOX_RELAY, converted.forwarders.firefoxRelay),
            helper.setToUser(userId, FORWARD_EMAIL, converted.forwarders.forwardEmail),
            helper.setToUser(userId, SIMPLE_LOGIN, converted.forwarders.simpleLogin),
        ]);
    });
}
function _65_migrate_forwarder_settings_deleteSettings(helper, userId, account) {
    return _65_migrate_forwarder_settings_awaiter(this, void 0, void 0, function* () {
        var _a;
        (_a = account === null || account === void 0 ? void 0 : account.settings) === null || _a === void 0 ? true : delete _a.usernameGenerationOptions;
        yield helper.set(userId, account);
    });
}

;// ../../libs/state/src/state-migrations/migrations/66-move-final-desktop-settings.ts
var _66_move_final_desktop_settings_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const _66_move_final_desktop_settings_DESKTOP_SETTINGS_DISK = {
    name: "desktopSettings",
};
const BROWSER_INTEGRATION_ENABLED = {
    key: "browserIntegrationEnabled",
    stateDefinition: _66_move_final_desktop_settings_DESKTOP_SETTINGS_DISK,
};
const BROWSER_INTEGRATION_FINGERPRINT_ENABLED = {
    key: "browserIntegrationFingerprintEnabled",
    stateDefinition: _66_move_final_desktop_settings_DESKTOP_SETTINGS_DISK,
};
const MINIMIZE_ON_COPY = {
    key: "minimizeOnCopy",
    stateDefinition: _66_move_final_desktop_settings_DESKTOP_SETTINGS_DISK,
};
class MoveFinalDesktopSettingsMigrator extends Migrator {
    migrate(helper) {
        return _66_move_final_desktop_settings_awaiter(this, void 0, void 0, function* () {
            const legacyGlobal = yield helper.get("global");
            const enableBrowserIntegrationValue = legacyGlobal === null || legacyGlobal === void 0 ? void 0 : legacyGlobal.enableBrowserIntegration;
            const enableBrowserIntegrationFingerprintValue = legacyGlobal === null || legacyGlobal === void 0 ? void 0 : legacyGlobal.enableBrowserIntegrationFingerprint;
            let updatedGlobal = false;
            if (enableBrowserIntegrationValue != null) {
                yield helper.setToGlobal(BROWSER_INTEGRATION_ENABLED, enableBrowserIntegrationValue);
                delete legacyGlobal.enableBrowserIntegration;
                updatedGlobal = true;
            }
            if (enableBrowserIntegrationFingerprintValue != null) {
                yield helper.setToGlobal(BROWSER_INTEGRATION_FINGERPRINT_ENABLED, enableBrowserIntegrationFingerprintValue);
                delete legacyGlobal.enableBrowserIntegrationFingerprint;
                updatedGlobal = true;
            }
            if (updatedGlobal) {
                yield helper.set("global", legacyGlobal);
            }
            function migrateAccount(userId, account) {
                return _66_move_final_desktop_settings_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const minimizeOnCopyToClipboardValue = (_a = account === null || account === void 0 ? void 0 : account.settings) === null || _a === void 0 ? void 0 : _a.minimizeOnCopyToClipboard;
                    if (minimizeOnCopyToClipboardValue != null) {
                        yield helper.setToUser(userId, MINIMIZE_ON_COPY, minimizeOnCopyToClipboardValue);
                        delete account.settings.minimizeOnCopyToClipboard;
                        yield helper.set(userId, account);
                    }
                });
            }
            const accounts = yield helper.getAccounts();
            yield Promise.all(accounts.map(({ userId, account }) => migrateAccount(userId, account)));
        });
    }
    rollback(helper) {
        return _66_move_final_desktop_settings_awaiter(this, void 0, void 0, function* () {
            const browserIntegrationEnabledValue = yield helper.getFromGlobal(BROWSER_INTEGRATION_ENABLED);
            const browserIntegrationFingerprintEnabled = yield helper.getFromGlobal(BROWSER_INTEGRATION_FINGERPRINT_ENABLED);
            if (browserIntegrationEnabledValue != null) {
                let legacyGlobal = yield helper.get("global");
                legacyGlobal !== null && legacyGlobal !== void 0 ? legacyGlobal : (legacyGlobal = {});
                legacyGlobal.enableBrowserIntegration = browserIntegrationEnabledValue;
                yield helper.set("global", legacyGlobal);
                yield helper.removeFromGlobal(BROWSER_INTEGRATION_ENABLED);
            }
            if (browserIntegrationFingerprintEnabled != null) {
                let legacyGlobal = yield helper.get("global");
                legacyGlobal !== null && legacyGlobal !== void 0 ? legacyGlobal : (legacyGlobal = {});
                legacyGlobal.enableBrowserIntegrationFingerprint = browserIntegrationFingerprintEnabled;
                yield helper.set("global", legacyGlobal);
                yield helper.removeFromGlobal(BROWSER_INTEGRATION_FINGERPRINT_ENABLED);
            }
            function rollbackAccount(userId, account) {
                return _66_move_final_desktop_settings_awaiter(this, void 0, void 0, function* () {
                    const minimizeOnCopyToClipboardValue = yield helper.getFromUser(userId, MINIMIZE_ON_COPY);
                    if (minimizeOnCopyToClipboardValue != null) {
                        account !== null && account !== void 0 ? account : (account = { settings: {} });
                        account.settings.minimizeOnCopyToClipboard = minimizeOnCopyToClipboardValue;
                        yield helper.set(userId, account);
                        yield helper.removeFromUser(userId, MINIMIZE_ON_COPY);
                    }
                });
            }
            const accounts = yield helper.getAccounts();
            yield Promise.all(accounts.map(({ userId, account }) => rollbackAccount(userId, account)));
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/67-remove-unassigned-items-banner-dismissed.ts
var _67_remove_unassigned_items_banner_dismissed_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const SHOW_BANNER = {
    key: "showBanner",
    stateDefinition: { name: "unassignedItemsBanner" },
};
class RemoveUnassignedItemsBannerDismissed extends Migrator {
    migrate(helper) {
        return _67_remove_unassigned_items_banner_dismissed_awaiter(this, void 0, void 0, function* () {
            yield Promise.all((yield helper.getAccounts()).map((_a) => _67_remove_unassigned_items_banner_dismissed_awaiter(this, [_a], void 0, function* ({ userId }) {
                if (helper.getFromUser(userId, SHOW_BANNER) != null) {
                    yield helper.removeFromUser(userId, SHOW_BANNER);
                }
            })));
        });
    }
    rollback(helper) {
        return _67_remove_unassigned_items_banner_dismissed_awaiter(this, void 0, void 0, function* () {
            throw IRREVERSIBLE;
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/68-move-last-sync-date.ts
var _68_move_last_sync_date_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const _68_move_last_sync_date_LAST_SYNC_KEY = {
    key: "lastSync",
    stateDefinition: {
        name: "sync",
    },
};
class MoveLastSyncDate extends Migrator {
    migrate(helper) {
        return _68_move_last_sync_date_awaiter(this, void 0, void 0, function* () {
            function migrateAccount(userId, account) {
                return _68_move_last_sync_date_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const value = (_a = account === null || account === void 0 ? void 0 : account.profile) === null || _a === void 0 ? void 0 : _a.lastSync;
                    if (value != null) {
                        yield helper.setToUser(userId, _68_move_last_sync_date_LAST_SYNC_KEY, value);
                        delete account.profile.lastSync;
                        yield helper.set(userId, account);
                    }
                });
            }
            const accounts = yield helper.getAccounts();
            yield Promise.all(accounts.map(({ userId, account }) => migrateAccount(userId, account)));
        });
    }
    rollback(helper) {
        return _68_move_last_sync_date_awaiter(this, void 0, void 0, function* () {
            function rollbackAccount(userId, account) {
                return _68_move_last_sync_date_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    const value = yield helper.getFromUser(userId, _68_move_last_sync_date_LAST_SYNC_KEY);
                    if (value != null) {
                        account !== null && account !== void 0 ? account : (account = {});
                        (_a = account.profile) !== null && _a !== void 0 ? _a : (account.profile = {});
                        account.profile.lastSync = value;
                        yield helper.set(userId, account);
                        yield helper.removeFromUser(userId, _68_move_last_sync_date_LAST_SYNC_KEY);
                    }
                });
            }
            const accounts = yield helper.getAccounts();
            yield Promise.all(accounts.map(({ userId, account }) => rollbackAccount(userId, account)));
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/69-migrate-incorrect-folder-key.ts
var _69_migrate_incorrect_folder_key_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const BAD_FOLDER_KEY = {
    key: "folder", // We inadvertently changed the key from "folders" to "folder"
    stateDefinition: {
        name: "folder",
    },
};
const GOOD_FOLDER_KEY = {
    key: "folders", // We should keep the key as "folders"
    stateDefinition: {
        name: "folder",
    },
};
class MigrateIncorrectFolderKey extends Migrator {
    migrate(helper) {
        return _69_migrate_incorrect_folder_key_awaiter(this, void 0, void 0, function* () {
            function migrateUser(userId) {
                return _69_migrate_incorrect_folder_key_awaiter(this, void 0, void 0, function* () {
                    const value = yield helper.getFromUser(userId, BAD_FOLDER_KEY);
                    if (value != null) {
                        yield helper.setToUser(userId, GOOD_FOLDER_KEY, value);
                    }
                    yield helper.removeFromUser(userId, BAD_FOLDER_KEY);
                });
            }
            const users = yield helper.getKnownUserIds();
            yield Promise.all(users.map((userId) => migrateUser(userId)));
        });
    }
    rollback(helper) {
        return _69_migrate_incorrect_folder_key_awaiter(this, void 0, void 0, function* () {
            function rollbackUser(userId) {
                return _69_migrate_incorrect_folder_key_awaiter(this, void 0, void 0, function* () {
                    const value = yield helper.getFromUser(userId, GOOD_FOLDER_KEY);
                    if (value != null) {
                        yield helper.setToUser(userId, BAD_FOLDER_KEY, value);
                    }
                    yield helper.removeFromUser(userId, GOOD_FOLDER_KEY);
                });
            }
            const users = yield helper.getKnownUserIds();
            yield Promise.all(users.map((userId) => rollbackUser(userId)));
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/7-move-biometric-auto-prompt-to-account.ts
var _7_move_biometric_auto_prompt_to_account_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

class MoveBiometricAutoPromptToAccount extends Migrator {
    migrate(helper) {
        return _7_move_biometric_auto_prompt_to_account_awaiter(this, void 0, void 0, function* () {
            var _a;
            const global = yield helper.get("global");
            const noAutoPromptBiometrics = (_a = global === null || global === void 0 ? void 0 : global.noAutoPromptBiometrics) !== null && _a !== void 0 ? _a : false;
            const accounts = yield helper.getAccounts();
            function updateAccount(userId, account) {
                return _7_move_biometric_auto_prompt_to_account_awaiter(this, void 0, void 0, function* () {
                    var _a;
                    if (account == null) {
                        return;
                    }
                    if (noAutoPromptBiometrics) {
                        account.settings = Object.assign((_a = account === null || account === void 0 ? void 0 : account.settings) !== null && _a !== void 0 ? _a : {}, {
                            disableAutoBiometricsPrompt: true,
                        });
                        yield helper.set(userId, account);
                    }
                });
            }
            delete global.noAutoPromptBiometrics;
            yield Promise.all([
                ...accounts.map(({ userId, account }) => updateAccount(userId, account)),
                helper.set("global", global),
            ]);
        });
    }
    rollback(helper) {
        return _7_move_biometric_auto_prompt_to_account_awaiter(this, void 0, void 0, function* () {
            throw IRREVERSIBLE;
        });
    }
    // Override is necessary because default implementation assumes `stateVersion` at the root, but for this version
    // it is nested inside a global object.
    updateVersion(helper, direction) {
        return _7_move_biometric_auto_prompt_to_account_awaiter(this, void 0, void 0, function* () {
            const endVersion = direction === "up" ? this.toVersion : this.fromVersion;
            helper.currentVersion = endVersion;
            const global = (yield helper.get("global")) || {};
            yield helper.set("global", Object.assign(Object.assign({}, global), { stateVersion: endVersion }));
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/70-remove-ac-banner-dismissed.ts
var _70_remove_ac_banner_dismissed_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const SHOW_BANNER_KEY = {
    key: "acBannersDismissed",
    stateDefinition: { name: "showProviderClientVaultPrivacyBanner" },
};
class RemoveAcBannersDismissed extends Migrator {
    migrate(helper) {
        return _70_remove_ac_banner_dismissed_awaiter(this, void 0, void 0, function* () {
            yield Promise.all((yield helper.getAccounts()).map((_a) => _70_remove_ac_banner_dismissed_awaiter(this, [_a], void 0, function* ({ userId }) {
                if (helper.getFromUser(userId, SHOW_BANNER_KEY) != null) {
                    yield helper.removeFromUser(userId, SHOW_BANNER_KEY);
                }
            })));
        });
    }
    rollback(helper) {
        return _70_remove_ac_banner_dismissed_awaiter(this, void 0, void 0, function* () {
            throw IRREVERSIBLE;
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/71-remove-new-customization-options-callout-dismissed.ts
var _71_remove_new_customization_options_callout_dismissed_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const SHOW_CALLOUT_KEY = {
    key: "newCustomizationOptionsCalloutDismissed",
    stateDefinition: { name: "bannersDismissed" },
};
class RemoveNewCustomizationOptionsCalloutDismissed extends Migrator {
    migrate(helper) {
        return _71_remove_new_customization_options_callout_dismissed_awaiter(this, void 0, void 0, function* () {
            yield Promise.all((yield helper.getAccounts()).map((_a) => _71_remove_new_customization_options_callout_dismissed_awaiter(this, [_a], void 0, function* ({ userId }) {
                if (helper.getFromUser(userId, SHOW_CALLOUT_KEY) != null) {
                    yield helper.removeFromUser(userId, SHOW_CALLOUT_KEY);
                }
            })));
        });
    }
    rollback(helper) {
        return _71_remove_new_customization_options_callout_dismissed_awaiter(this, void 0, void 0, function* () {
            throw IRREVERSIBLE;
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/72-remove-account-deprovisioning-banner-dismissed.ts
var _72_remove_account_deprovisioning_banner_dismissed_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const _72_remove_account_deprovisioning_banner_dismissed_SHOW_BANNER_KEY = {
    key: "showAccountDeprovisioningBanner",
    stateDefinition: { name: "accountDeprovisioningBanner" },
};
class RemoveAccountDeprovisioningBannerDismissed extends Migrator {
    migrate(helper) {
        return _72_remove_account_deprovisioning_banner_dismissed_awaiter(this, void 0, void 0, function* () {
            yield Promise.all((yield helper.getAccounts()).map((_a) => _72_remove_account_deprovisioning_banner_dismissed_awaiter(this, [_a], void 0, function* ({ userId }) {
                if (helper.getFromUser(userId, _72_remove_account_deprovisioning_banner_dismissed_SHOW_BANNER_KEY) != null) {
                    yield helper.removeFromUser(userId, _72_remove_account_deprovisioning_banner_dismissed_SHOW_BANNER_KEY);
                }
            })));
        });
    }
    rollback(helper) {
        return _72_remove_account_deprovisioning_banner_dismissed_awaiter(this, void 0, void 0, function* () {
            throw IRREVERSIBLE;
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/73-add-master-password-unlock-data.ts
var _73_add_master_password_unlock_data_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const _73_add_master_password_unlock_data_ACCOUNT_ACCOUNTS = {
    stateDefinition: {
        name: "account",
    },
    key: "accounts",
};
const MASTER_PASSWORD_UNLOCK_KEY = {
    key: "masterPasswordUnlockKey",
    stateDefinition: { name: "masterPasswordUnlock" },
};
const MASTER_KEY_ENCRYPTED_USER_KEY = {
    key: "masterKeyEncryptedUserKey",
    stateDefinition: { name: "masterPassword" },
};
const _73_add_master_password_unlock_data_KDF_CONFIG_DISK = {
    key: "kdfConfig",
    stateDefinition: { name: "kdfConfig" },
};
class AddMasterPasswordUnlockData extends Migrator {
    migrate(helper) {
        return _73_add_master_password_unlock_data_awaiter(this, void 0, void 0, function* () {
            function migrateAccount(userId, account) {
                return _73_add_master_password_unlock_data_awaiter(this, void 0, void 0, function* () {
                    const email = account === null || account === void 0 ? void 0 : account.email;
                    const kdfConfig = yield helper.getFromUser(userId, _73_add_master_password_unlock_data_KDF_CONFIG_DISK);
                    const masterKeyEncryptedUserKey = yield helper.getFromUser(userId, MASTER_KEY_ENCRYPTED_USER_KEY);
                    if ((yield helper.getFromUser(userId, MASTER_PASSWORD_UNLOCK_KEY)) == null &&
                        email != null &&
                        kdfConfig != null &&
                        masterKeyEncryptedUserKey != null) {
                        yield helper.setToUser(userId, MASTER_PASSWORD_UNLOCK_KEY, {
                            salt: email.trim().toLowerCase(),
                            kdf: kdfConfig,
                            masterKeyWrappedUserKey: masterKeyEncryptedUserKey,
                        });
                    }
                });
            }
            const accountDictionary = yield helper.getFromGlobal(_73_add_master_password_unlock_data_ACCOUNT_ACCOUNTS);
            const accounts = yield helper.getAccounts();
            yield Promise.all(accounts.map(({ userId }) => migrateAccount(userId, accountDictionary[userId])));
        });
    }
    rollback(helper) {
        return _73_add_master_password_unlock_data_awaiter(this, void 0, void 0, function* () {
            function rollbackAccount(userId) {
                return _73_add_master_password_unlock_data_awaiter(this, void 0, void 0, function* () {
                    if ((yield helper.getFromUser(userId, MASTER_PASSWORD_UNLOCK_KEY)) != null) {
                        yield helper.removeFromUser(userId, MASTER_PASSWORD_UNLOCK_KEY);
                    }
                });
            }
            const accounts = yield helper.getAccounts();
            yield Promise.all(accounts.map(({ userId }) => rollbackAccount(userId)));
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/74-remove-legacy-pin.ts
var _74_remove_legacy_pin_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const PinProtectedUserKey = {
    key: "pinKeyEncryptedUserKeyPersistent",
    stateDefinition: {
        name: "pinUnlock",
    },
};
class RemoveLegacyPin extends Migrator {
    migrate(helper) {
        return _74_remove_legacy_pin_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            function migrateAccount(userId, account) {
                return _74_remove_legacy_pin_awaiter(this, void 0, void 0, function* () {
                    const pinProtectedUserKey = yield helper.getFromUser(userId, PinProtectedUserKey);
                    if (pinProtectedUserKey != null) {
                        yield helper.removeFromUser(userId, PinProtectedUserKey);
                    }
                });
            }
            yield Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
        });
    }
    rollback(helper) {
        return _74_remove_legacy_pin_awaiter(this, void 0, void 0, function* () {
            throw IRREVERSIBLE;
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/75-remove-user-encrypted-private-key.ts
var _75_remove_user_encrypted_private_key_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const userEncryptedPrivateKey = {
    key: "privateKey",
    stateDefinition: {
        name: "crypto",
    },
};
const userKeyEncryptedSigningKey = {
    key: "userSigningKey",
    stateDefinition: {
        name: "crypto",
    },
};
const userSignedPublicKey = {
    key: "userSignedPublicKey",
    stateDefinition: {
        name: "crypto",
    },
};
const accountSecurityState = {
    key: "accountSecurityState",
    stateDefinition: {
        name: "crypto",
    },
};
const accountCryptographicState = {
    key: "accountCryptographicState",
    stateDefinition: {
        name: "crypto",
    },
};
class RemoveUserEncryptedPrivateKey extends Migrator {
    migrate(helper) {
        return _75_remove_user_encrypted_private_key_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            for (const { userId } of accounts) {
                // Check if account cryptographic state already exists
                const existingAccountCryptoState = yield helper.getFromUser(userId, accountCryptographicState);
                // Gather all individual cryptographic key state parts
                const privateKey = yield helper.getFromUser(userId, userEncryptedPrivateKey);
                const signingKey = yield helper.getFromUser(userId, userKeyEncryptedSigningKey);
                const signedPubKey = yield helper.getFromUser(userId, userSignedPublicKey);
                const accountSecurity = yield helper.getFromUser(userId, accountSecurityState);
                // Only migrate if account cryptographic state does not exist
                if (!existingAccountCryptoState) {
                    // Build the new account cryptographic state object
                    let newAccountCryptographicState;
                    if (privateKey != null &&
                        signingKey == null &&
                        signedPubKey == null &&
                        accountSecurity == null) {
                        newAccountCryptographicState = { V1: { private_key: privateKey } };
                        yield helper.setToUser(userId, accountCryptographicState, newAccountCryptographicState);
                    }
                    else if (privateKey != null &&
                        signingKey != null &&
                        signedPubKey != null &&
                        accountSecurity != null) {
                        newAccountCryptographicState = {
                            V2: {
                                private_key: privateKey,
                                signing_key: signingKey,
                                signed_public_key: signedPubKey,
                                security_state: accountSecurity,
                            },
                        };
                        yield helper.setToUser(userId, accountCryptographicState, newAccountCryptographicState);
                    }
                    else {
                        helper.logService.warning(`Incomplete cryptographic state for user ${userId}, skipping migration of account cryptographic state.`);
                    }
                }
                // Always remove the old states
                if (privateKey != null) {
                    yield helper.removeFromUser(userId, userEncryptedPrivateKey);
                }
                if (signingKey != null) {
                    yield helper.removeFromUser(userId, userKeyEncryptedSigningKey);
                }
                if (signedPubKey != null) {
                    yield helper.removeFromUser(userId, userSignedPublicKey);
                }
                if (accountSecurity != null) {
                    yield helper.removeFromUser(userId, accountSecurityState);
                }
            }
        });
    }
    rollback(helper) {
        return _75_remove_user_encrypted_private_key_awaiter(this, void 0, void 0, function* () {
            throw IRREVERSIBLE;
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/76-migrate-popup-width-options.ts
var _76_migrate_popup_width_options_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

/** Maps old popup width option keys to their new equivalents. */
const OLD_TO_NEW_WIDTH_MAP = {
    wide: "default",
    "extra-wide": "wide",
};
const POPUP_WIDTH_KEY = {
    key: "popup-width",
    stateDefinition: { name: "popupStyle" },
};
class MigratePopupWidthOptions extends Migrator {
    migrate(helper) {
        return _76_migrate_popup_width_options_awaiter(this, void 0, void 0, function* () {
            const currentWidth = yield helper.getFromGlobal(POPUP_WIDTH_KEY);
            if (currentWidth != null && currentWidth in OLD_TO_NEW_WIDTH_MAP) {
                yield helper.setToGlobal(POPUP_WIDTH_KEY, OLD_TO_NEW_WIDTH_MAP[currentWidth]);
            }
        });
    }
    rollback(helper) {
        return _76_migrate_popup_width_options_awaiter(this, void 0, void 0, function* () {
            throw IRREVERSIBLE;
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/77-clear-clipboard-delay-to-string.ts
var _77_clear_clipboard_delay_to_string_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

// Old integer values that might exist in user data
const OLD_CLEAR_CLIPBOARD_DELAY_VALUES = {
    NEVER: null,
    TEN_SECONDS: 10,
    TWENTY_SECONDS: 20,
    THIRTY_SECONDS: 30,
    ONE_MINUTE: 60,
    TWO_MINUTES: 120,
    FIVE_MINUTES: 300,
};
// New string values
const NEW_CLEAR_CLIPBOARD_DELAY_VALUES = {
    NEVER: "never",
    TEN_SECONDS: "tenSeconds",
    TWENTY_SECONDS: "twentySeconds",
    THIRTY_SECONDS: "thirtySeconds",
    ONE_MINUTE: "oneMinute",
    TWO_MINUTES: "twoMinutes",
    FIVE_MINUTES: "fiveMinutes",
};
const CLEAR_CLIPBOARD_DELAY_KEY = {
    stateDefinition: {
        name: "autofillSettingsLocal",
    },
    key: "clearClipboardDelay",
};
const HAD_PRE_MIGRATION_CLIPBOARD_VALUE_KEY = {
    stateDefinition: {
        name: "autofillSettingsLocal",
    },
    key: "hadPreMigrationClipboardValue",
};
class ClearClipboardDelayToStringMigrator extends Migrator {
    migrate(helper) {
        return _77_clear_clipboard_delay_to_string_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            yield Promise.all(accounts.map(({ userId }) => this.migrateAccount(helper, userId)));
        });
    }
    migrateAccount(helper, userId) {
        return _77_clear_clipboard_delay_to_string_awaiter(this, void 0, void 0, function* () {
            const oldValue = yield helper.getFromUser(userId, CLEAR_CLIPBOARD_DELAY_KEY);
            // Skip if no value exists (will use default "fiveMinutes")
            if (oldValue === undefined) {
                return;
            }
            // Only set flag for users who had null (old "Never") before migration.
            // These users will be migrated to "fiveMinutes" (the new default),
            // so they should see a notification that the default has changed.
            if (oldValue === null) {
                yield helper.setToUser(userId, HAD_PRE_MIGRATION_CLIPBOARD_VALUE_KEY, true);
            }
            let newValue;
            // Convert old integer/null values to new string values
            switch (oldValue) {
                case null:
                    newValue = NEW_CLEAR_CLIPBOARD_DELAY_VALUES.FIVE_MINUTES;
                    break;
                case 10:
                    newValue = NEW_CLEAR_CLIPBOARD_DELAY_VALUES.TEN_SECONDS;
                    break;
                case 20:
                    newValue = NEW_CLEAR_CLIPBOARD_DELAY_VALUES.TWENTY_SECONDS;
                    break;
                case 30:
                    newValue = NEW_CLEAR_CLIPBOARD_DELAY_VALUES.THIRTY_SECONDS;
                    break;
                case 60:
                    newValue = NEW_CLEAR_CLIPBOARD_DELAY_VALUES.ONE_MINUTE;
                    break;
                case 120:
                    newValue = NEW_CLEAR_CLIPBOARD_DELAY_VALUES.TWO_MINUTES;
                    break;
                case 300:
                    newValue = NEW_CLEAR_CLIPBOARD_DELAY_VALUES.FIVE_MINUTES;
                    break;
                default:
                    // For any unknown values, default to fiveMinutes
                    newValue = NEW_CLEAR_CLIPBOARD_DELAY_VALUES.FIVE_MINUTES;
                    break;
            }
            // Set the new string value
            yield helper.setToUser(userId, CLEAR_CLIPBOARD_DELAY_KEY, newValue);
        });
    }
    rollback(helper) {
        return _77_clear_clipboard_delay_to_string_awaiter(this, void 0, void 0, function* () {
            const accounts = yield helper.getAccounts();
            yield Promise.all(accounts.map(({ userId }) => this.rollbackAccount(helper, userId)));
        });
    }
    rollbackAccount(helper, userId) {
        return _77_clear_clipboard_delay_to_string_awaiter(this, void 0, void 0, function* () {
            // Remove the flag on rollback
            yield helper.setToUser(userId, HAD_PRE_MIGRATION_CLIPBOARD_VALUE_KEY, undefined);
            const newValue = yield helper.getFromUser(userId, CLEAR_CLIPBOARD_DELAY_KEY);
            // Skip if no value exists
            if (newValue === undefined) {
                return;
            }
            let oldValue;
            // Convert new string values back to old integer/null values
            switch (newValue) {
                case "never":
                    oldValue = OLD_CLEAR_CLIPBOARD_DELAY_VALUES.NEVER;
                    break;
                case "tenSeconds":
                    oldValue = OLD_CLEAR_CLIPBOARD_DELAY_VALUES.TEN_SECONDS;
                    break;
                case "twentySeconds":
                    oldValue = OLD_CLEAR_CLIPBOARD_DELAY_VALUES.TWENTY_SECONDS;
                    break;
                case "thirtySeconds":
                    oldValue = OLD_CLEAR_CLIPBOARD_DELAY_VALUES.THIRTY_SECONDS;
                    break;
                case "oneMinute":
                    oldValue = OLD_CLEAR_CLIPBOARD_DELAY_VALUES.ONE_MINUTE;
                    break;
                case "twoMinutes":
                    oldValue = OLD_CLEAR_CLIPBOARD_DELAY_VALUES.TWO_MINUTES;
                    break;
                case "fiveMinutes":
                    // Potential data loss: both null (old "Never") and 300 (old "5 minutes") migrate to
                    // "fiveMinutes", so on rollback both become 300. Users who originally had null/"Never"
                    // will end up with 300/"5 minutes" instead — an acceptable trade-off for a rollback edge case.
                    oldValue = OLD_CLEAR_CLIPBOARD_DELAY_VALUES.FIVE_MINUTES;
                    break;
                default:
                    // Default fallback
                    oldValue = OLD_CLEAR_CLIPBOARD_DELAY_VALUES.NEVER;
                    break;
            }
            // Set the old integer/null value
            yield helper.setToUser(userId, CLEAR_CLIPBOARD_DELAY_KEY, oldValue);
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/8-move-state-version.ts
var _8_move_state_version_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

class MoveStateVersionMigrator extends Migrator {
    migrate(helper) {
        return _8_move_state_version_awaiter(this, void 0, void 0, function* () {
            const global = yield helper.get("global");
            if (global.stateVersion) {
                yield helper.set("stateVersion", global.stateVersion);
                delete global.stateVersion;
                yield helper.set("global", global);
            }
            else {
                throw new Error("Migration failed, state version not found");
            }
        });
    }
    rollback(helper) {
        return _8_move_state_version_awaiter(this, void 0, void 0, function* () {
            const version = yield helper.get("stateVersion");
            const global = yield helper.get("global");
            yield helper.set("global", Object.assign(Object.assign({}, global), { stateVersion: version }));
            yield helper.set("stateVersion", undefined);
        });
    }
    // Override is necessary because default implementation assumes `stateVersion` at the root, but this migration moves
    // it from a `global` object to root.This makes for unique rollback versioning.
    updateVersion(helper, direction) {
        return _8_move_state_version_awaiter(this, void 0, void 0, function* () {
            const endVersion = direction === "up" ? this.toVersion : this.fromVersion;
            helper.currentVersion = endVersion;
            if (direction === "up") {
                yield helper.set("stateVersion", endVersion);
            }
            else {
                const global = (yield helper.get("global")) || {};
                yield helper.set("global", Object.assign(Object.assign({}, global), { stateVersion: endVersion }));
            }
        });
    }
}

;// ../../libs/state/src/state-migrations/migrations/9-move-browser-settings-to-global.ts
var _9_move_browser_settings_to_global_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

class MoveBrowserSettingsToGlobal extends Migrator {
    // Will first check if any of the accounts have a value from the given accountSelector
    // if they do have a value it will set that value into global state but if multiple
    // users have differing values it will prefer the false setting,
    // if all users have true then it will take true.
    tryAddSetting(accounts, accountSelector, globalSetter) {
        const hasValue = accounts.some(({ account }) => {
            return accountSelector(account) !== undefined;
        });
        if (hasValue) {
            const value = !accounts.some(({ account }) => {
                var _a;
                return ((_a = accountSelector(account)) !== null && _a !== void 0 ? _a : false) === false;
            });
            globalSetter(value);
        }
    }
    migrate(helper) {
        return _9_move_browser_settings_to_global_awaiter(this, void 0, void 0, function* () {
            const global = yield helper.get("global");
            const accounts = yield helper.getAccounts();
            const globalNeverDomainsValue = accounts.reduce((accumulator, { account }) => {
                var _a, _b;
                const normalizedNeverDomains = (_b = (_a = account.settings) === null || _a === void 0 ? void 0 : _a.neverDomains) !== null && _b !== void 0 ? _b : {};
                for (const [id, value] of Object.entries(normalizedNeverDomains)) {
                    accumulator !== null && accumulator !== void 0 ? accumulator : (accumulator = {});
                    accumulator[id] = value;
                }
                return accumulator;
            }, undefined);
            const targetGlobalState = {};
            if (globalNeverDomainsValue != null) {
                targetGlobalState.neverDomains = globalNeverDomainsValue;
            }
            this.tryAddSetting(accounts, (a) => { var _a; return (_a = a.settings) === null || _a === void 0 ? void 0 : _a.disableAddLoginNotification; }, (v) => (targetGlobalState.disableAddLoginNotification = v));
            this.tryAddSetting(accounts, (a) => { var _a; return (_a = a.settings) === null || _a === void 0 ? void 0 : _a.disableChangedPasswordNotification; }, (v) => (targetGlobalState.disableChangedPasswordNotification = v));
            this.tryAddSetting(accounts, (a) => { var _a; return (_a = a.settings) === null || _a === void 0 ? void 0 : _a.disableContextMenuItem; }, (v) => (targetGlobalState.disableContextMenuItem = v));
            yield helper.set("global", Object.assign(Object.assign({}, global), targetGlobalState));
            yield Promise.all(accounts.map((_a) => _9_move_browser_settings_to_global_awaiter(this, [_a], void 0, function* ({ userId, account }) {
                var _b, _c, _d, _e;
                (_b = account.settings) === null || _b === void 0 ? true : delete _b.disableAddLoginNotification;
                (_c = account.settings) === null || _c === void 0 ? true : delete _c.disableChangedPasswordNotification;
                (_d = account.settings) === null || _d === void 0 ? true : delete _d.disableContextMenuItem;
                (_e = account.settings) === null || _e === void 0 ? true : delete _e.neverDomains;
                yield helper.set(userId, account);
            })));
        });
    }
    rollback(helper) {
        throw new Error("Method not implemented.");
    }
}

;// ../../libs/state/src/state-migrations/migrations/min-version.ts
var min_version_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};


function minVersionError(current) {
    return `Your local data is too old to be migrated. Your current state version is ${current}, but minimum version is ${MIN_VERSION}.`;
}
class MinVersionMigrator extends Migrator {
    constructor() {
        super(0, MIN_VERSION);
    }
    // Overrides the default implementation to catch any version that may be passed in.
    shouldMigrate(helper) {
        return Promise.resolve(helper.currentVersion < MIN_VERSION);
    }
    migrate(helper) {
        return min_version_awaiter(this, void 0, void 0, function* () {
            if (helper.currentVersion < MIN_VERSION) {
                throw new Error(minVersionError(helper.currentVersion));
            }
        });
    }
    rollback(helper) {
        return min_version_awaiter(this, void 0, void 0, function* () {
            throw IRREVERSIBLE;
        });
    }
}

;// ../../libs/state/src/state-migrations/migrate.ts
var migrate_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};












































































const MIN_VERSION = 3;
const CURRENT_VERSION = 77;
function createMigrationBuilder() {
    return MigrationBuilder.create()
        .with(MinVersionMigrator)
        .with(RemoveEverBeenUnlockedMigrator, 3, 4)
        .with(AddKeyTypeToOrgKeysMigrator, 4, 5)
        .with(RemoveLegacyEtmKeyMigrator, 5, 6)
        .with(MoveBiometricAutoPromptToAccount, 6, 7)
        .with(MoveStateVersionMigrator, 7, 8)
        .with(MoveBrowserSettingsToGlobal, 8, 9)
        .with(EverHadUserKeyMigrator, 9, 10)
        .with(OrganizationKeyMigrator, 10, 11)
        .with(MoveEnvironmentStateToProviders, 11, 12)
        .with(ProviderKeyMigrator, 12, 13)
        .with(MoveBiometricClientKeyHalfToStateProviders, 13, 14)
        .with(FolderMigrator, 14, 15)
        .with(LastSyncMigrator, 15, 16)
        .with(EnablePasskeysMigrator, 16, 17)
        .with(AutofillSettingsKeyMigrator, 17, 18)
        .with(RequirePasswordOnStartMigrator, 18, 19)
        .with(PrivateKeyMigrator, 19, 20)
        .with(CollectionMigrator, 20, 21)
        .with(CollapsedGroupingsMigrator, 21, 22)
        .with(MoveBiometricPromptsToStateProviders, 22, 23)
        .with(SmOnboardingTasksMigrator, 23, 24)
        .with(ClearClipboardDelayMigrator, 24, 25)
        .with(RevertLastSyncMigrator, 25, 26)
        .with(BadgeSettingsMigrator, 26, 27)
        .with(MoveBiometricUnlockToStateProviders, 27, 28)
        .with(UserNotificationSettingsKeyMigrator, 28, 29)
        .with(PolicyMigrator, 29, 30)
        .with(EnableContextMenuMigrator, 30, 31)
        .with(PreferredLanguageMigrator, 31, 32)
        .with(AppIdMigrator, 32, 33)
        .with(DomainSettingsMigrator, 33, 34)
        .with(MoveThemeToStateProviderMigrator, 34, 35)
        .with(VaultSettingsKeyMigrator, 35, 36)
        .with(AvatarColorMigrator, 36, 37)
        .with(TokenServiceStateProviderMigrator, 37, 38)
        .with(MoveBillingAccountProfileMigrator, 38, 39)
        .with(OrganizationMigrator, 39, 40)
        .with(EventCollectionMigrator, 40, 41)
        .with(EnableFaviconMigrator, 41, 42)
        .with(AutoConfirmFingerPrintsMigrator, 42, 43)
        .with(UserDecryptionOptionsMigrator, 43, 44)
        .with(MergeEnvironmentState, 44, 45)
        .with(DeleteBiometricPromptCancelledData, 45, 46)
        .with(MoveDesktopSettingsMigrator, 46, 47)
        .with(MoveDdgToStateProviderMigrator, 47, 48)
        .with(AccountServerConfigMigrator, 48, 49)
        .with(KeyConnectorMigrator, 49, 50)
        .with(RememberedEmailMigrator, 50, 51)
        .with(DeleteInstalledVersion, 51, 52)
        .with(DeviceTrustServiceStateProviderMigrator, 52, 53)
        .with(SendMigrator, 53, 54)
        .with(MoveMasterKeyStateToProviderMigrator, 54, 55)
        .with(AuthRequestMigrator, 55, 56)
        .with(CipherServiceMigrator, 56, 57)
        .with(RemoveRefreshTokenMigratedFlagMigrator, 57, 58)
        .with(KdfConfigMigrator, 58, 59)
        .with(KnownAccountsMigrator, 59, 60)
        .with(PinStateMigrator, 60, 61)
        .with(VaultTimeoutSettingsServiceStateProviderMigrator, 61, 62)
        .with(PasswordOptionsMigrator, 62, 63)
        .with(GeneratorHistoryMigrator, 63, 64)
        .with(ForwarderOptionsMigrator, 64, 65)
        .with(MoveFinalDesktopSettingsMigrator, 65, 66)
        .with(RemoveUnassignedItemsBannerDismissed, 66, 67)
        .with(MoveLastSyncDate, 67, 68)
        .with(MigrateIncorrectFolderKey, 68, 69)
        .with(RemoveAcBannersDismissed, 69, 70)
        .with(RemoveNewCustomizationOptionsCalloutDismissed, 70, 71)
        .with(RemoveAccountDeprovisioningBannerDismissed, 71, 72)
        .with(AddMasterPasswordUnlockData, 72, 73)
        .with(RemoveLegacyPin, 73, 74)
        .with(RemoveUserEncryptedPrivateKey, 74, 75)
        .with(MigratePopupWidthOptions, 75, 76)
        .with(ClearClipboardDelayToStringMigrator, 76, CURRENT_VERSION);
}
function currentVersion(storageService, logService) {
    return migrate_awaiter(this, void 0, void 0, function* () {
        var _a;
        let state = yield storageService.get("stateVersion");
        if (state == null) {
            // Pre v8
            state = (_a = (yield storageService.get("global"))) === null || _a === void 0 ? void 0 : _a.stateVersion;
        }
        if (state == null) {
            logService.info("No state version found, assuming empty state.");
            return -1;
        }
        logService.info(`State version: ${state}`);
        return state;
    });
}
/**
 * Waits for migrations to have a chance to run and will resolve the promise once they are.
 *
 * @param storageService Disk storage where the `stateVersion` will or is already saved in.
 * @param logService Log service
 */
function waitForMigrations(storageService, logService) {
    return migrate_awaiter(this, void 0, void 0, function* () {
        const isReady = () => migrate_awaiter(this, void 0, void 0, function* () {
            const version = yield currentVersion(storageService, logService);
            // The saved version is what we consider the latest
            // migrations should be complete, the state version
            // shouldn't become larger than `CURRENT_VERSION` in
            // any normal usage of the application but it is common
            // enough in dev scenarios where we want to consider that
            // ready as well and return true in that scenario.
            return version >= CURRENT_VERSION;
        });
        const wait = (time) => migrate_awaiter(this, void 0, void 0, function* () {
            // Wait exponentially
            const nextTime = time * 2;
            if (nextTime > 8192) {
                // Don't wait longer than ~8 seconds in a single wait,
                // if the migrations still haven't happened. They aren't
                // likely to.
                return;
            }
            return new Promise((resolve) => {
                setTimeout(() => migrate_awaiter(this, void 0, void 0, function* () {
                    if (!(yield isReady())) {
                        logService.info(`Waiting for migrations to finish, waiting for ${nextTime}ms`);
                        yield wait(nextTime);
                    }
                    resolve();
                }), time);
            });
        });
        if (!(yield isReady())) {
            // Wait for 2ms to start with
            yield wait(2);
        }
    });
}

;// ../../libs/state/src/state-migrations/migration-helper.ts
var migration_helper_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
class MigrationHelper {
    constructor(currentVersion, storageService, logService, type, clientType) {
        this.currentVersion = currentVersion;
        this.storageService = storageService;
        this.logService = logService;
        this.clientType = clientType;
        this.type = type;
    }
    /**
     * Gets a value from the storage service at the given key.
     *
     * This is a brute force method to just get a value from the storage service. If you can use {@link getFromGlobal} or {@link getFromUser}, you should.
     * @param key location
     * @returns the value at the location
     */
    get(key) {
        return this.storageService.get(key);
    }
    /**
     * Sets a value in the storage service at the given key.
     *
     * This is a brute force method to just set a value in the storage service. If you can use {@link setToGlobal} or {@link setToUser}, you should.
     * @param key location
     * @param value the value to set
     * @returns
     */
    set(key, value) {
        this.logService.info(`Setting ${key}`);
        return this.storageService.save(key, value);
    }
    /**
     * Remove a value in the storage service at the given key.
     *
     * This is a brute force method to just remove a value in the storage service. If you can use {@link removeFromGlobal} or {@link removeFromUser}, you should.
     * @param key location
     * @returns void
     */
    remove(key) {
        this.logService.info(`Removing ${key}`);
        return this.storageService.remove(key);
    }
    /**
     * Gets a globally scoped value from a location derived through the key definition
     *
     * This is for use with the state providers framework, DO NOT use for values stored with {@link StateService},
     * use {@link get} for those.
     * @param keyDefinition unique key definition
     * @returns value from store
     */
    getFromGlobal(keyDefinition) {
        return this.get(this.getGlobalKey(keyDefinition));
    }
    /**
     * Sets a globally scoped value to a location derived through the key definition
     *
     * This is for use with the state providers framework, DO NOT use for values stored with {@link StateService},
     * use {@link set} for those.
     * @param keyDefinition unique key definition
     * @param value value to store
     * @returns void
     */
    setToGlobal(keyDefinition, value) {
        return this.set(this.getGlobalKey(keyDefinition), value);
    }
    /**
     * Remove a globally scoped location derived through the key definition
     *
     * This is for use with the state providers framework, DO NOT use for values stored with {@link StateService},
     * use {@link remove} for those.
     * @param keyDefinition unique key definition
     * @returns void
     */
    removeFromGlobal(keyDefinition) {
        return this.remove(this.getGlobalKey(keyDefinition));
    }
    /**
     * Gets a user scoped value from a location derived through the user id and key definition
     *
     * This is for use with the state providers framework, DO NOT use for values stored with {@link StateService},
     * use {@link get} for those.
     * @param userId userId to use in the key
     * @param keyDefinition unique key definition
     * @returns value from store
     */
    getFromUser(userId, keyDefinition) {
        return this.get(this.getUserKey(userId, keyDefinition));
    }
    /**
     * Sets a user scoped value to a location derived through the user id and key definition
     *
     * This is for use with the state providers framework, DO NOT use for values stored with {@link StateService},
     * use {@link set} for those.
     * @param userId userId to use in the key
     * @param keyDefinition unique key definition
     * @param value value to store
     * @returns void
     */
    setToUser(userId, keyDefinition, value) {
        return this.set(this.getUserKey(userId, keyDefinition), value);
    }
    /**
     * Remove a user scoped location derived through the key definition
     *
     * This is for use with the state providers framework, DO NOT use for values stored with {@link StateService},
     * use {@link remove} for those.
     * @param keyDefinition unique key definition
     * @returns void
     */
    removeFromUser(userId, keyDefinition) {
        return this.remove(this.getUserKey(userId, keyDefinition));
    }
    info(message) {
        this.logService.info(message);
    }
    /**
     * Helper method to read all Account objects stored by the State Service.
     *
     * This is useful from creating migrations off of this paradigm, but should not be used once a value is migrated to a state provider.
     *
     * @returns a list of all accounts that have been authenticated with state service, cast the expected type.
     */
    getAccounts() {
        return migration_helper_awaiter(this, void 0, void 0, function* () {
            const userIds = yield this.getKnownUserIds();
            return Promise.all(userIds.map((userId) => migration_helper_awaiter(this, void 0, void 0, function* () {
                return ({
                    userId,
                    account: yield this.get(userId),
                });
            })));
        });
    }
    /**
     * Helper method to read known users ids.
     */
    getKnownUserIds() {
        return migration_helper_awaiter(this, void 0, void 0, function* () {
            if (this.currentVersion < 60) {
                return knownAccountUserIdsBuilderPre60(this.storageService);
            }
            else {
                return knownAccountUserIdsBuilder(this.storageService);
            }
        });
    }
    /**
     * Builds a user storage key appropriate for the current version.
     *
     * @param userId userId to use in the key
     * @param keyDefinition state and key to use in the key
     * @returns
     */
    getUserKey(userId, keyDefinition) {
        if (this.currentVersion < 9) {
            return userKeyBuilderPre9();
        }
        else {
            return userKeyBuilder(userId, keyDefinition);
        }
    }
    /**
     * Builds a global storage key appropriate for the current version.
     *
     * @param keyDefinition state and key to use in the key
     * @returns
     */
    getGlobalKey(keyDefinition) {
        if (this.currentVersion < 9) {
            return globalKeyBuilderPre9();
        }
        else {
            return globalKeyBuilder(keyDefinition);
        }
    }
}
/**
 * When this is updated, rename this function to `userKeyBuilderXToY` where `X` is the version number it
 * became relevant, and `Y` prior to the version it was updated.
 *
 * Be sure to update the map in `MigrationHelper` to point to the appropriate function for the current version.
 * @param userId The userId of the user you want the key to be for.
 * @param keyDefinition the key definition of which data the key should point to.
 * @returns
 */
function userKeyBuilder(userId, keyDefinition) {
    return `user_${userId}_${keyDefinition.stateDefinition.name}_${keyDefinition.key}`;
}
function userKeyBuilderPre9() {
    throw Error("No key builder should be used for versions prior to 9.");
}
/**
 * When this is updated, rename this function to `globalKeyBuilderXToY` where `X` is the version number
 * it became relevant, and `Y` prior to the version it was updated.
 *
 * Be sure to update the map in `MigrationHelper` to point to the appropriate function for the current version.
 * @param keyDefinition the key definition of which data the key should point to.
 * @returns
 */
function globalKeyBuilder(keyDefinition) {
    return `global_${keyDefinition.stateDefinition.name}_${keyDefinition.key}`;
}
function globalKeyBuilderPre9() {
    throw Error("No key builder should be used for versions prior to 9.");
}
function knownAccountUserIdsBuilderPre60(storageService) {
    return migration_helper_awaiter(this, void 0, void 0, function* () {
        var _a;
        return (_a = (yield storageService.get("authenticatedAccounts"))) !== null && _a !== void 0 ? _a : [];
    });
}
function knownAccountUserIdsBuilder(storageService) {
    return migration_helper_awaiter(this, void 0, void 0, function* () {
        const accounts = yield storageService.get(globalKeyBuilder({ stateDefinition: { name: "account" }, key: "accounts" }));
        return Object.keys(accounts !== null && accounts !== void 0 ? accounts : {});
    });
}

;// ../../libs/state/src/state-migrations/index.ts





;// ../../libs/state/src/index.ts
// Root barrel for @bitwarden/state





;// ../../libs/state-internal/src/default-active-user-state.ts
var default_active_user_state_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


class DefaultActiveUserState {
    constructor(keyDefinition, activeUserId$, singleUserStateProvider) {
        this.keyDefinition = keyDefinition;
        this.activeUserId$ = activeUserId$;
        this.singleUserStateProvider = singleUserStateProvider;
        this.combinedState$ = this.activeUserId$.pipe((0,external_rxjs_namespaceObject.switchMap)((userId) => userId != null
            ? this.singleUserStateProvider.get(userId, this.keyDefinition).combinedState$
            : external_rxjs_namespaceObject.NEVER));
        // State should just be combined state without the user id
        this.state$ = this.combinedState$.pipe((0,external_rxjs_namespaceObject.map)(([_userId, state]) => state));
    }
    update(configureState_1) {
        return default_active_user_state_awaiter(this, arguments, void 0, function* (configureState, options = {}) {
            const userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.activeUserId$.pipe((0,external_rxjs_namespaceObject.timeout)({
                first: 1000,
                with: () => (0,external_rxjs_namespaceObject.throwError)(() => new Error(`Timeout while retrieving active user for key ${this.keyDefinition.fullName}.`)),
            })));
            if (userId == null) {
                throw new Error(`Error storing ${this.keyDefinition.fullName} for the active user: No active user at this time.`);
            }
            return [
                userId,
                yield this.singleUserStateProvider
                    .get(userId, this.keyDefinition)
                    .update(configureState, options),
            ];
        });
    }
}

;// ../../libs/state-internal/src/default-active-user-state.provider.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


class DefaultActiveUserStateProvider {
    constructor(activeAccountAccessor, singleUserStateProvider) {
        this.activeAccountAccessor = activeAccountAccessor;
        this.singleUserStateProvider = singleUserStateProvider;
        this.activeUserId$ = this.activeAccountAccessor.activeUserId$.pipe(
        // To avoid going to storage when we don't need to, only get updates when there is a true change.
        (0,external_rxjs_namespaceObject.distinctUntilChanged)((a, b) => (a == null || b == null ? a == b : a === b)));
    }
    get(keyDefinition) {
        // All other providers cache the creation of their corresponding `State` objects, this instance
        // doesn't need to do that since it calls `SingleUserStateProvider` it will go through their caching
        // layer, because of that, the creation of this instance is quite simple and not worth caching.
        return new DefaultActiveUserState(keyDefinition, this.activeUserId$, this.singleUserStateProvider);
    }
}

;// ../../libs/state-internal/src/default-derived-state.ts
var default_derived_state_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

/**
 * Default derived state
 */
class DefaultDerivedState {
    constructor(parentState$, deriveDefinition, dependencies) {
        this.parentState$ = parentState$;
        this.deriveDefinition = deriveDefinition;
        this.dependencies = dependencies;
        this.forcedValueSubject = new external_rxjs_namespaceObject.Subject();
        this.storageKey = deriveDefinition.storageKey;
        const derivedState$ = this.parentState$.pipe((0,external_rxjs_namespaceObject.concatMap)((state) => default_derived_state_awaiter(this, void 0, void 0, function* () {
            let derivedStateOrPromise = this.deriveDefinition.derive(state, this.dependencies);
            if (derivedStateOrPromise instanceof Promise) {
                derivedStateOrPromise = yield derivedStateOrPromise;
            }
            const derivedState = derivedStateOrPromise;
            return derivedState;
        })));
        this.state$ = (0,external_rxjs_namespaceObject.merge)(this.forcedValueSubject, derivedState$).pipe((0,external_rxjs_namespaceObject.share)({
            connector: () => {
                return new external_rxjs_namespaceObject.ReplaySubject(1);
            },
            resetOnRefCountZero: () => (0,external_rxjs_namespaceObject.timer)(this.deriveDefinition.cleanupDelayMs),
        }));
    }
    forceValue(value) {
        return default_derived_state_awaiter(this, void 0, void 0, function* () {
            this.forcedValueSubject.next(value);
            return value;
        });
    }
}

;// ../../libs/state-internal/src/default-derived-state.provider.ts

class DefaultDerivedStateProvider {
    constructor() {
        /**
         * The cache uses a WeakMap to maintain separate derived states per user.
         * Each user's state Observable acts as a unique key, without needing to
         * pass around `userId`. Also, when a user's state Observable is cleaned up
         * (like during an account swap) their cache is automatically garbage
         * collected.
         */
        this.cache = new WeakMap();
    }
    get(parentState$, deriveDefinition, dependencies) {
        let stateCache = this.cache.get(parentState$);
        if (!stateCache) {
            stateCache = {};
            this.cache.set(parentState$, stateCache);
        }
        const cacheKey = deriveDefinition.buildCacheKey();
        const existingDerivedState = stateCache[cacheKey];
        if (existingDerivedState != null) {
            // I have to cast out of the unknown generic but this should be safe if rules
            // around domain token are made
            return existingDerivedState;
        }
        const newDerivedState = this.buildDerivedState(parentState$, deriveDefinition, dependencies);
        stateCache[cacheKey] = newDerivedState;
        return newDerivedState;
    }
    buildDerivedState(parentState$, deriveDefinition, dependencies) {
        return new DefaultDerivedState(parentState$, deriveDefinition, dependencies);
    }
}

;// ../../libs/state-internal/src/util.ts
var util_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
function getStoredValue(key, storage, deserializer) {
    return util_awaiter(this, void 0, void 0, function* () {
        if (storage.valuesRequireDeserialization) {
            const jsonValue = yield storage.get(key);
            return deserializer(jsonValue);
        }
        else {
            const value = yield storage.get(key);
            return value !== null && value !== void 0 ? value : null;
        }
    });
}
/**
 * Creates a {@link StorageKey}
 * @param keyDefinition The key definition of which data the key should point to.
 * @returns A key that is ready to be used in a storage service to get data.
 */
function util_globalKeyBuilder(keyDefinition) {
    return `global_${keyDefinition.stateDefinition.name}_${keyDefinition.key}`;
}
function populateOptionsWithDefault(options) {
    const { combineLatestWith = null, shouldUpdate = () => true, msTimeout = 1000 } = options;
    return {
        combineLatestWith: combineLatestWith,
        shouldUpdate: shouldUpdate,
        msTimeout: msTimeout,
    };
}

;// ../../libs/state-internal/src/state-base.ts
var state_base_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


class StateBase {
    constructor(key, storageService, keyDefinition, logService) {
        this.key = key;
        this.storageService = storageService;
        this.keyDefinition = keyDefinition;
        this.logService = logService;
        const storageUpdate$ = storageService.updates$.pipe((0,external_rxjs_namespaceObject.filter)((storageUpdate) => storageUpdate.key === key), (0,external_rxjs_namespaceObject.switchMap)((storageUpdate) => state_base_awaiter(this, void 0, void 0, function* () {
            if (storageUpdate.updateType === "remove") {
                return null;
            }
            return yield getStoredValue(key, storageService, keyDefinition.deserializer);
        })));
        let state$ = (0,external_rxjs_namespaceObject.merge)((0,external_rxjs_namespaceObject.defer)(() => getStoredValue(key, storageService, keyDefinition.deserializer)), storageUpdate$);
        if (keyDefinition.debug.enableRetrievalLogging) {
            state$ = state$.pipe((0,external_rxjs_namespaceObject.tap)({
                next: (v) => {
                    this.logService.info(`Retrieving '${key}' from storage, value is ${v == null ? "null" : "non-null"}`);
                },
            }));
        }
        // If 0 cleanup is chosen, treat this as absolutely no cache
        if (keyDefinition.cleanupDelayMs !== 0) {
            state$ = state$.pipe((0,external_rxjs_namespaceObject.share)({
                connector: () => new external_rxjs_namespaceObject.ReplaySubject(1),
                resetOnRefCountZero: () => (0,external_rxjs_namespaceObject.timer)(keyDefinition.cleanupDelayMs),
            }));
        }
        this.state$ = state$;
    }
    update(configureState_1) {
        return state_base_awaiter(this, arguments, void 0, function* (configureState, options = {}) {
            const normalizedOptions = populateOptionsWithDefault(options);
            if (this.updatePromise != null) {
                yield this.updatePromise;
            }
            try {
                this.updatePromise = this.internalUpdate(configureState, normalizedOptions);
                return yield this.updatePromise;
            }
            finally {
                this.updatePromise = null;
            }
        });
    }
    internalUpdate(configureState, options) {
        return state_base_awaiter(this, void 0, void 0, function* () {
            const currentState = yield this.getStateForUpdate();
            const combinedDependencies = options.combineLatestWith != null
                ? yield (0,external_rxjs_namespaceObject.firstValueFrom)(options.combineLatestWith.pipe((0,external_rxjs_namespaceObject.timeout)(options.msTimeout)))
                : null;
            if (!options.shouldUpdate(currentState, combinedDependencies)) {
                return currentState;
            }
            const newState = configureState(currentState, combinedDependencies);
            yield this.doStorageSave(newState, currentState);
            return newState;
        });
    }
    doStorageSave(newState, oldState) {
        return state_base_awaiter(this, void 0, void 0, function* () {
            if (this.keyDefinition.debug.enableUpdateLogging) {
                this.logService.info(`Updating '${this.key}' from ${oldState == null ? "null" : "non-null"} to ${newState == null ? "null" : "non-null"}`);
            }
            yield this.storageService.save(this.key, newState);
        });
    }
    /** For use in update methods, does not wait for update to complete before yielding state.
     * The expectation is that that await is already done
     */
    getStateForUpdate() {
        return state_base_awaiter(this, void 0, void 0, function* () {
            return yield getStoredValue(this.key, this.storageService, this.keyDefinition.deserializer);
        });
    }
}

;// ../../libs/state-internal/src/default-global-state.ts


class DefaultGlobalState extends StateBase {
    constructor(keyDefinition, chosenLocation, logService) {
        super(util_globalKeyBuilder(keyDefinition), chosenLocation, keyDefinition, logService);
    }
}

;// ../../libs/state-internal/src/default-global-state.provider.ts

class DefaultGlobalStateProvider {
    constructor(storageServiceProvider, logService) {
        this.storageServiceProvider = storageServiceProvider;
        this.logService = logService;
        this.globalStateCache = {};
    }
    get(keyDefinition) {
        const [location, storageService] = this.storageServiceProvider.get(keyDefinition.stateDefinition.defaultStorageLocation, keyDefinition.stateDefinition.storageLocationOverrides);
        const cacheKey = this.buildCacheKey(location, keyDefinition);
        const existingGlobalState = this.globalStateCache[cacheKey];
        if (existingGlobalState != null) {
            // The cast into the actual generic is safe because of rules around key definitions
            // being unique.
            return existingGlobalState;
        }
        const newGlobalState = new DefaultGlobalState(keyDefinition, storageService, this.logService);
        this.globalStateCache[cacheKey] = newGlobalState;
        return newGlobalState;
    }
    buildCacheKey(location, keyDefinition) {
        return `${location}_${keyDefinition.fullName}`;
    }
}

;// ../../libs/state-internal/src/default-single-user-state.ts
var default_single_user_state_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};


class DefaultSingleUserState extends StateBase {
    constructor(userId, keyDefinition, chosenLocation, stateEventRegistrarService, logService) {
        super(keyDefinition.buildKey(userId), chosenLocation, keyDefinition, logService);
        this.userId = userId;
        this.stateEventRegistrarService = stateEventRegistrarService;
        this.combinedState$ = (0,external_rxjs_namespaceObject.combineLatest)([(0,external_rxjs_namespaceObject.of)(userId), this.state$]);
    }
    doStorageSave(newState, oldState) {
        const _super = Object.create(null, {
            doStorageSave: { get: () => super.doStorageSave }
        });
        return default_single_user_state_awaiter(this, void 0, void 0, function* () {
            yield _super.doStorageSave.call(this, newState, oldState);
            yield this.stateEventRegistrarService.registerEvents(this.keyDefinition);
        });
    }
}

;// ../../libs/state-internal/src/default-single-user-state.provider.ts

class DefaultSingleUserStateProvider {
    constructor(storageServiceProvider, stateEventRegistrarService, logService) {
        this.storageServiceProvider = storageServiceProvider;
        this.stateEventRegistrarService = stateEventRegistrarService;
        this.logService = logService;
        this.cache = {};
    }
    get(userId, keyDefinition) {
        const [location, storageService] = this.storageServiceProvider.get(keyDefinition.stateDefinition.defaultStorageLocation, keyDefinition.stateDefinition.storageLocationOverrides);
        const cacheKey = this.buildCacheKey(location, userId, keyDefinition);
        const existingUserState = this.cache[cacheKey];
        if (existingUserState != null) {
            // I have to cast out of the unknown generic but this should be safe if rules
            // around domain token are made
            return existingUserState;
        }
        const newUserState = new DefaultSingleUserState(userId, keyDefinition, storageService, this.stateEventRegistrarService, this.logService);
        this.cache[cacheKey] = newUserState;
        return newUserState;
    }
    buildCacheKey(location, userId, keyDefinition) {
        return `${location}_${keyDefinition.fullName}_${userId}`;
    }
}

;// ../../libs/state-internal/src/default-state.provider.ts
var default_state_provider_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

class DefaultStateProvider {
    constructor(activeUserStateProvider, singleUserStateProvider, globalStateProvider, derivedStateProvider) {
        this.activeUserStateProvider = activeUserStateProvider;
        this.singleUserStateProvider = singleUserStateProvider;
        this.globalStateProvider = globalStateProvider;
        this.derivedStateProvider = derivedStateProvider;
        this.getActive = this.activeUserStateProvider.get.bind(this.activeUserStateProvider);
        this.getUser = this.singleUserStateProvider.get.bind(this.singleUserStateProvider);
        this.getGlobal = this.globalStateProvider.get.bind(this.globalStateProvider);
        this.getDerived = this.derivedStateProvider.get.bind(this.derivedStateProvider);
        this.activeUserId$ = this.activeUserStateProvider.activeUserId$;
    }
    getUserState$(userKeyDefinition, userId) {
        if (userId) {
            return this.getUser(userId, userKeyDefinition).state$;
        }
        else {
            return this.activeUserId$.pipe((0,external_rxjs_namespaceObject.filter)((userId) => userId != null), // Filter out null-ish user ids since we can't get state for a null user id
            (0,external_rxjs_namespaceObject.take)(1), (0,external_rxjs_namespaceObject.switchMap)((userId) => this.getUser(userId, userKeyDefinition).state$));
        }
    }
    getUserStateOrDefault$(userKeyDefinition, config) {
        const { userId, defaultValue = null } = config;
        if (userId) {
            return this.getUser(userId, userKeyDefinition).state$;
        }
        else {
            return this.activeUserId$.pipe((0,external_rxjs_namespaceObject.take)(1), (0,external_rxjs_namespaceObject.switchMap)((userId) => userId != null ? this.getUser(userId, userKeyDefinition).state$ : (0,external_rxjs_namespaceObject.of)(defaultValue)));
        }
    }
    setUserState(userKeyDefinition, value, userId) {
        return default_state_provider_awaiter(this, void 0, void 0, function* () {
            if (userId) {
                return [userId, yield this.getUser(userId, userKeyDefinition).update(() => value)];
            }
            else {
                return yield this.getActive(userKeyDefinition).update(() => value);
            }
        });
    }
}

;// ../../libs/state-internal/src/inline-derived-state.ts
var inline_derived_state_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

class InlineDerivedStateProvider {
    get(parentState$, deriveDefinition, dependencies) {
        return new InlineDerivedState(parentState$, deriveDefinition, dependencies);
    }
}
class InlineDerivedState {
    constructor(parentState$, deriveDefinition, dependencies) {
        this.state$ = parentState$.pipe(concatMap((value) => inline_derived_state_awaiter(this, void 0, void 0, function* () { return yield deriveDefinition.derive(value, dependencies); })));
    }
    forceValue(value) {
        // No need to force anything, we don't keep a cache
        return Promise.resolve(value);
    }
}

;// ../../libs/state-internal/src/legacy/global-state.ts
class GlobalState {
}

;// ../../libs/state-internal/src/legacy/default-state.service.ts
var default_state_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};


const keys = {
    global: "global",
};
const partialKeys = {
    userAutoKey: "_user_auto",
    userBiometricKey: "_user_biometric",
};
const DDG_SHARED_KEY = "DuckDuckGoSharedKey";
class DefaultStateService {
    constructor(storageService, secureStorageService, activeUserAccessor) {
        this.storageService = storageService;
        this.secureStorageService = secureStorageService;
        this.activeUserAccessor = activeUserAccessor;
    }
    clean(options) {
        return default_state_service_awaiter(this, void 0, void 0, function* () {
            yield this.setUserKeyAutoUnlock(null, options);
            yield this.clearUserKeyBiometric(options.userId);
        });
    }
    /**
     * user key when using the "never" option of vault timeout
     */
    getUserKeyAutoUnlock(options) {
        return default_state_service_awaiter(this, void 0, void 0, function* () {
            if (options.userId == null) {
                return null;
            }
            return yield this.secureStorageService.get(`${options.userId}${partialKeys.userAutoKey}`, {
                userId: options.userId,
                keySuffix: "auto",
            });
        });
    }
    /**
     * user key when using the "never" option of vault timeout
     */
    setUserKeyAutoUnlock(value, options) {
        return default_state_service_awaiter(this, void 0, void 0, function* () {
            if (options.userId == null) {
                return;
            }
            yield this.saveSecureStorageKey(partialKeys.userAutoKey, value, options.userId, "auto");
        });
    }
    clearUserKeyBiometric(userId) {
        return default_state_service_awaiter(this, void 0, void 0, function* () {
            if (userId == null) {
                return;
            }
            yield this.saveSecureStorageKey(partialKeys.userBiometricKey, null, userId, "biometric");
        });
    }
    getDuckDuckGoSharedKey() {
        return default_state_service_awaiter(this, void 0, void 0, function* () {
            const userId = yield this.getActiveUserIdFromStorage();
            if (userId == null) {
                return null;
            }
            return yield this.secureStorageService.get(DDG_SHARED_KEY);
        });
    }
    setDuckDuckGoSharedKey(value) {
        return default_state_service_awaiter(this, void 0, void 0, function* () {
            const userId = yield this.getActiveUserIdFromStorage();
            if (userId == null) {
                return;
            }
            value == null
                ? yield this.secureStorageService.remove(DDG_SHARED_KEY)
                : yield this.secureStorageService.save(DDG_SHARED_KEY, value);
        });
    }
    setEnableDuckDuckGoBrowserIntegration(value) {
        return default_state_service_awaiter(this, void 0, void 0, function* () {
            var _a;
            const globals = (_a = (yield this.storageService.get(keys.global))) !== null && _a !== void 0 ? _a : new GlobalState();
            globals.enableDuckDuckGoBrowserIntegration = value;
            yield this.storageService.save(keys.global, globals);
        });
    }
    getActiveUserIdFromStorage() {
        return default_state_service_awaiter(this, void 0, void 0, function* () {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.activeUserAccessor.activeUserId$);
        });
    }
    saveSecureStorageKey(key, value, userId, keySuffix) {
        return default_state_service_awaiter(this, void 0, void 0, function* () {
            return value == null
                ? yield this.secureStorageService.remove(`${userId}${key}`, { keySuffix: keySuffix })
                : yield this.secureStorageService.save(`${userId}${key}`, value, {
                    keySuffix: keySuffix,
                });
        });
    }
}

;// ../../libs/state-internal/src/default-state-event-registrar.service.ts
var default_state_event_registrar_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const STATE_LOCK_EVENT = KeyDefinition.array(CLEAR_EVENT_DISK, "lock", {
    deserializer: (e) => e,
});
const STATE_LOGOUT_EVENT = KeyDefinition.array(CLEAR_EVENT_DISK, "logout", {
    deserializer: (e) => e,
});
class DefaultStateEventRegistrarService {
    constructor(globalStateProvider, storageServiceProvider) {
        this.storageServiceProvider = storageServiceProvider;
        this.stateEventStateMap = {
            lock: globalStateProvider.get(STATE_LOCK_EVENT),
            logout: globalStateProvider.get(STATE_LOGOUT_EVENT),
        };
    }
    registerEvents(keyDefinition) {
        return default_state_event_registrar_service_awaiter(this, void 0, void 0, function* () {
            for (const clearEvent of keyDefinition.clearOn) {
                const eventState = this.stateEventStateMap[clearEvent];
                // Determine the storage location for this
                const [storageLocation] = this.storageServiceProvider.get(keyDefinition.stateDefinition.defaultStorageLocation, keyDefinition.stateDefinition.storageLocationOverrides);
                const newEvent = {
                    state: keyDefinition.stateDefinition.name,
                    key: keyDefinition.key,
                    location: storageLocation,
                };
                // Only update the event state if the existing list doesn't have a matching entry
                yield eventState.update((existingTickets) => {
                    existingTickets !== null && existingTickets !== void 0 ? existingTickets : (existingTickets = []);
                    existingTickets.push(newEvent);
                    return existingTickets;
                }, {
                    shouldUpdate: (currentTickets) => {
                        return (
                        // If the current tickets are null, then it will for sure be added
                        currentTickets == null ||
                            // If an existing match couldn't be found, we also need to add one
                            currentTickets.findIndex((e) => e.state === newEvent.state &&
                                e.key === newEvent.key &&
                                e.location === newEvent.location) === -1);
                    },
                });
            }
        });
    }
}

;// ../../libs/state-internal/src/default-state-event-runner.service.ts
var default_state_event_runner_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};



class DefaultStateEventRunnerService {
    constructor(globalStateProvider, storageServiceProvider) {
        this.storageServiceProvider = storageServiceProvider;
        this.stateEventMap = {
            lock: globalStateProvider.get(STATE_LOCK_EVENT),
            logout: globalStateProvider.get(STATE_LOGOUT_EVENT),
        };
    }
    handleEvent(event, userId) {
        return default_state_event_runner_service_awaiter(this, void 0, void 0, function* () {
            let tickets = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.stateEventMap[event].state$);
            tickets !== null && tickets !== void 0 ? tickets : (tickets = []);
            const failures = [];
            for (const ticket of tickets) {
                try {
                    const [, service] = this.storageServiceProvider.get(ticket.location, {});
                    const ticketStorageKey = this.storageKeyFor(userId, ticket);
                    // Evaluate current value so we can avoid writing to state if we don't need to
                    const currentValue = yield service.get(ticketStorageKey);
                    if (currentValue != null) {
                        yield service.remove(ticketStorageKey);
                    }
                }
                catch (err) {
                    let errorMessage = "Unknown Error";
                    if (err != null &&
                        typeof err === "object" &&
                        "message" in err &&
                        typeof err.message === "string") {
                        errorMessage = err.message;
                    }
                    failures.push(`${errorMessage} in ${ticket.state} > ${ticket.key} located ${ticket.location}`);
                }
            }
            if (failures.length > 0) {
                // Throw aggregated error
                throw new Error(`One or more errors occurred while handling event '${event}' for user ${userId}.\n${failures.join("\n")}`);
            }
        });
    }
    storageKeyFor(userId, ticket) {
        const userKey = new UserKeyDefinition(new StateDefinition(ticket.state, ticket.location), ticket.key, {
            deserializer: (v) => v,
            clearOn: [],
        });
        return userKey.buildKey(userId);
    }
}

;// ../../libs/state-internal/src/index.ts

















;// ../../libs/common/src/platform/state/index.ts



;// ../../libs/common/src/auth/services/account.service.ts
var account_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore



const account_service_ACCOUNT_ACCOUNTS = KeyDefinition.record(ACCOUNT_DISK, "accounts", {
    deserializer: (accountInfo) => (Object.assign(Object.assign({}, accountInfo), { creationDate: accountInfo.creationDate ? new Date(accountInfo.creationDate) : undefined })),
});
const account_service_ACCOUNT_ACTIVE_ACCOUNT_ID = new KeyDefinition(ACCOUNT_DISK, "activeAccountId", {
    deserializer: (id) => id,
});
const account_service_ACCOUNT_ACTIVITY = KeyDefinition.record(ACCOUNT_DISK, "activity", {
    deserializer: (activity) => new Date(activity),
});
const ACCOUNT_VERIFY_NEW_DEVICE_LOGIN = new UserKeyDefinition(ACCOUNT_DISK, "verifyNewDeviceLogin", {
    deserializer: (verifyDevices) => verifyDevices,
    clearOn: ["logout"],
});
const LOGGED_OUT_INFO = {
    email: "",
    emailVerified: false,
    name: undefined,
    creationDate: undefined,
};
/**
 * An rxjs map operator that extracts the UserId from an account, or throws if the account or UserId are null.
 */
const account_service_getUserId = (0,external_rxjs_namespaceObject.map)((account) => {
    if (account == null) {
        throw new Error("Null or undefined account");
    }
    return account.id;
});
/**
 * An rxjs map operator that extracts the UserId from an account, or returns undefined if the account or UserId are null.
 */
const getOptionalUserId = (0,external_rxjs_namespaceObject.map)((account) => { var _a; return (_a = account === null || account === void 0 ? void 0 : account.id) !== null && _a !== void 0 ? _a : null; });
class AccountServiceImplementation {
    constructor(messagingService, logService, globalStateProvider, singleUserStateProvider) {
        this.messagingService = messagingService;
        this.logService = logService;
        this.globalStateProvider = globalStateProvider;
        this.singleUserStateProvider = singleUserStateProvider;
        this._showHeader$ = new external_rxjs_namespaceObject.BehaviorSubject(true);
        this.showHeader$ = this._showHeader$.asObservable();
        this.accountsState = this.globalStateProvider.get(account_service_ACCOUNT_ACCOUNTS);
        this.activeAccountIdState = this.globalStateProvider.get(account_service_ACCOUNT_ACTIVE_ACCOUNT_ID);
        this.accounts$ = this.accountsState.state$.pipe((0,external_rxjs_namespaceObject.map)((accounts) => (accounts == null ? {} : accounts)));
        this.activeAccount$ = this.activeAccountIdState.state$.pipe((0,external_rxjs_namespaceObject.combineLatestWith)(this.accounts$), (0,external_rxjs_namespaceObject.map)(([id, accounts]) => (id ? Object.assign({ id }, accounts[id]) : null)), (0,external_rxjs_namespaceObject.distinctUntilChanged)((a, b) => (a === null || a === void 0 ? void 0 : a.id) === (b === null || b === void 0 ? void 0 : b.id) && this.accountInfoEqual(a, b)), (0,external_rxjs_namespaceObject.shareReplay)({ bufferSize: 1, refCount: false }));
        this.accountActivity$ = this.globalStateProvider
            .get(account_service_ACCOUNT_ACTIVITY)
            .state$.pipe((0,external_rxjs_namespaceObject.map)((activity) => activity !== null && activity !== void 0 ? activity : {}));
        this.sortedUserIds$ = this.accountActivity$.pipe((0,external_rxjs_namespaceObject.map)((activity) => {
            return Object.entries(activity)
                .map(([userId, lastActive]) => ({ userId, lastActive }))
                .sort((a, b) => b.lastActive.getTime() - a.lastActive.getTime()) // later dates first
                .map((a) => a.userId);
        }));
        this.nextUpAccount$ = (0,external_rxjs_namespaceObject.combineLatest)([
            this.accounts$,
            this.activeAccount$,
            this.sortedUserIds$,
        ]).pipe((0,external_rxjs_namespaceObject.map)(([accounts, activeAccount, sortedUserIds]) => {
            const nextId = sortedUserIds.find((id) => id !== (activeAccount === null || activeAccount === void 0 ? void 0 : activeAccount.id) && accounts[id] != null);
            return nextId ? Object.assign({ id: nextId }, accounts[nextId]) : null;
        }));
        this.accountVerifyNewDeviceLogin$ = this.activeAccountIdState.state$.pipe((0,external_rxjs_namespaceObject.switchMap)((userId) => this.singleUserStateProvider.get(userId, ACCOUNT_VERIFY_NEW_DEVICE_LOGIN).state$));
    }
    addAccount(userId, accountData) {
        return account_service_awaiter(this, void 0, void 0, function* () {
            if (!utils_Utils.isGuid(userId)) {
                throw new Error("userId is required");
            }
            yield this.accountsState.update((accounts) => {
                accounts || (accounts = {});
                accounts[userId] = accountData;
                return accounts;
            });
            yield this.setAccountActivity(userId, new Date());
        });
    }
    setAccountName(userId, name) {
        return account_service_awaiter(this, void 0, void 0, function* () {
            yield this.setAccountInfo(userId, { name });
        });
    }
    setAccountEmail(userId, email) {
        return account_service_awaiter(this, void 0, void 0, function* () {
            yield this.setAccountInfo(userId, { email });
        });
    }
    setAccountEmailVerified(userId, emailVerified) {
        return account_service_awaiter(this, void 0, void 0, function* () {
            yield this.setAccountInfo(userId, { emailVerified });
        });
    }
    setAccountCreationDate(userId, creationDate) {
        return account_service_awaiter(this, void 0, void 0, function* () {
            yield this.setAccountInfo(userId, { creationDate });
        });
    }
    clean(userId) {
        return account_service_awaiter(this, void 0, void 0, function* () {
            yield this.setAccountInfo(userId, LOGGED_OUT_INFO);
            yield this.removeAccountActivity(userId);
        });
    }
    switchAccount(userId) {
        return account_service_awaiter(this, void 0, void 0, function* () {
            let updateActivity = false;
            yield this.activeAccountIdState.update((_, __) => {
                updateActivity = true;
                return userId;
            }, {
                combineLatestWith: this.accountsState.state$.pipe((0,external_rxjs_namespaceObject.filter)((accounts) => {
                    if (userId == null) {
                        // Don't worry about accounts when we are about to set active user to null
                        return true;
                    }
                    return (accounts === null || accounts === void 0 ? void 0 : accounts[userId]) != null;
                }), 
                // If we don't get the desired account with enough time, just return empty as that will result in the same error
                (0,external_rxjs_namespaceObject.timeout)({ first: 1000, with: () => (0,external_rxjs_namespaceObject.of)({}) })),
                shouldUpdate: (id, accounts) => {
                    if (userId != null && (accounts === null || accounts === void 0 ? void 0 : accounts[userId]) == null) {
                        throw new Error("Account does not exist");
                    }
                    // update only if userId changes
                    return id !== userId;
                },
            });
            if (updateActivity) {
                yield this.setAccountActivity(userId, new Date());
            }
        });
    }
    setAccountActivity(userId, lastActivity) {
        return account_service_awaiter(this, void 0, void 0, function* () {
            if (!utils_Utils.isGuid(userId)) {
                // only store for valid userIds
                return;
            }
            yield this.globalStateProvider.get(account_service_ACCOUNT_ACTIVITY).update((activity) => {
                activity || (activity = {});
                activity[userId] = lastActivity;
                return activity;
            }, {
                shouldUpdate: (oldActivity) => { var _a; return ((_a = oldActivity === null || oldActivity === void 0 ? void 0 : oldActivity[userId]) === null || _a === void 0 ? void 0 : _a.getTime()) !== (lastActivity === null || lastActivity === void 0 ? void 0 : lastActivity.getTime()); },
            });
        });
    }
    setAccountVerifyNewDeviceLogin(userId, setVerifyNewDeviceLogin) {
        return account_service_awaiter(this, void 0, void 0, function* () {
            if (!utils_Utils.isGuid(userId)) {
                // only store for valid userIds
                return;
            }
            yield this.singleUserStateProvider
                .get(userId, ACCOUNT_VERIFY_NEW_DEVICE_LOGIN)
                .update(() => setVerifyNewDeviceLogin, {
                shouldUpdate: (previousValue) => previousValue !== setVerifyNewDeviceLogin,
            });
        });
    }
    removeAccountActivity(userId) {
        return account_service_awaiter(this, void 0, void 0, function* () {
            yield this.globalStateProvider.get(account_service_ACCOUNT_ACTIVITY).update((activity) => {
                if (activity == null) {
                    return activity;
                }
                delete activity[userId];
                return activity;
            }, { shouldUpdate: (oldActivity) => (oldActivity === null || oldActivity === void 0 ? void 0 : oldActivity[userId]) != null });
        });
    }
    // TODO: update to use our own account status settings. Requires inverting direction of state service accounts flow
    delete() {
        return account_service_awaiter(this, void 0, void 0, function* () {
            var _a;
            try {
                (_a = this.messagingService) === null || _a === void 0 ? void 0 : _a.send("logout");
            }
            catch (e) {
                this.logService.error(e);
                throw e;
            }
        });
    }
    setShowHeader(visible) {
        return account_service_awaiter(this, void 0, void 0, function* () {
            this._showHeader$.next(visible);
        });
    }
    accountInfoEqual(a, b) {
        var _a, _b;
        if (a == null && b == null) {
            return true;
        }
        if (a == null || b == null) {
            return false;
        }
        return (a.email === b.email &&
            a.emailVerified === b.emailVerified &&
            a.name === b.name &&
            ((_a = a.creationDate) === null || _a === void 0 ? void 0 : _a.getTime()) === ((_b = b.creationDate) === null || _b === void 0 ? void 0 : _b.getTime()));
    }
    setAccountInfo(userId, update) {
        return account_service_awaiter(this, void 0, void 0, function* () {
            function newAccountInfo(oldAccountInfo) {
                return Object.assign(Object.assign({}, oldAccountInfo), update);
            }
            yield this.accountsState.update((accounts) => {
                accounts[userId] = newAccountInfo(accounts[userId]);
                return accounts;
            }, {
                // Avoid unnecessary updates
                // TODO: Faster comparison, maybe include a hash on the objects?
                shouldUpdate: (accounts) => {
                    if ((accounts === null || accounts === void 0 ? void 0 : accounts[userId]) == null) {
                        throw new Error("Account does not exist");
                    }
                    return !this.accountInfoEqual(accounts[userId], newAccountInfo(accounts[userId]));
                },
            });
        });
    }
}

;// ../../libs/common/src/models/response/base.response.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
class BaseResponse {
    constructor(response) {
        this.response = response;
    }
    getResponseProperty(propertyName, response = null, exactName = false) {
        if (propertyName == null || propertyName === "") {
            throw new Error("propertyName must not be null/empty.");
        }
        if (response == null && this.response != null) {
            response = this.response;
        }
        if (response == null) {
            return null;
        }
        if (!exactName && response[propertyName] === undefined) {
            let otherCasePropertyName = null;
            if (propertyName.charAt(0) === propertyName.charAt(0).toUpperCase()) {
                otherCasePropertyName = propertyName.charAt(0).toLowerCase();
            }
            else {
                otherCasePropertyName = propertyName.charAt(0).toUpperCase();
            }
            if (propertyName.length > 1) {
                otherCasePropertyName += propertyName.slice(1);
            }
            propertyName = otherCasePropertyName;
            if (response[propertyName] === undefined) {
                propertyName = propertyName.toLowerCase();
            }
            if (response[propertyName] === undefined) {
                propertyName = propertyName.toUpperCase();
            }
        }
        return response[propertyName];
    }
}

;// ../../libs/common/src/models/response/error.response.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

class ErrorResponse extends BaseResponse {
    constructor(response, status, identityResponse) {
        super(response);
        let errorModel = null;
        if (response != null) {
            const responseErrorModel = this.getResponseProperty("ErrorModel");
            if (responseErrorModel && identityResponse) {
                errorModel = responseErrorModel;
            }
            else {
                errorModel = response;
            }
        }
        if (status === 429) {
            this.message = "Rate limit exceeded. Try again later.";
        }
        else if (errorModel) {
            this.message = this.getResponseProperty("Message", errorModel);
            this.validationErrors = this.getResponseProperty("ValidationErrors", errorModel);
        }
        this.statusCode = status;
    }
    getSingleMessage() {
        if (this.validationErrors == null) {
            return this.message;
        }
        for (const key in this.validationErrors) {
            // eslint-disable-next-line
            if (!this.validationErrors.hasOwnProperty(key)) {
                continue;
            }
            if (this.validationErrors[key].length) {
                return this.validationErrors[key][0];
            }
        }
        return this.message;
    }
    getAllMessages() {
        const messages = [];
        if (this.validationErrors == null) {
            return messages;
        }
        for (const key in this.validationErrors) {
            // eslint-disable-next-line
            if (!this.validationErrors.hasOwnProperty(key)) {
                continue;
            }
            this.validationErrors[key].forEach((item) => {
                let prefix = "";
                if (key.indexOf("[") > -1 && key.indexOf("]") > -1) {
                    const lastSep = key.lastIndexOf(".");
                    prefix = key.substr(0, lastSep > -1 ? lastSep : key.length) + ": ";
                }
                messages.push(prefix + item);
            });
        }
        return messages;
    }
}

;// ./src/models/response.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

function getErrorMessage(error) {
    if (typeof error === "string") {
        return error;
    }
    if (error instanceof ErrorResponse) {
        const message = error.getSingleMessage();
        if (message) {
            return message;
        }
    }
    if (error instanceof Error) {
        return String(error);
    }
    if (error) {
        const errorWithMessage = error; // To placate TypeScript.
        if (errorWithMessage.message && typeof errorWithMessage.message === "string") {
            return errorWithMessage.message;
        }
    }
    return JSON.stringify(error);
}
class response_Response {
    static error(error, data) {
        const res = new response_Response();
        res.success = false;
        res.message = getErrorMessage(error);
        res.data = data;
        return res;
    }
    static notFound() {
        return response_Response.error("Not found.");
    }
    static noEditPermission() {
        return response_Response.error("You do not have permission to edit this item");
    }
    static badRequest(message) {
        return response_Response.error(message);
    }
    static multipleResults(ids) {
        let msg = "More than one result was found. Try getting a specific object by `id` instead. " +
            "The following objects were found:";
        ids.forEach((id) => {
            msg += "\n" + id;
        });
        return response_Response.error(msg, ids);
    }
    static success(data) {
        const res = new response_Response();
        res.success = true;
        res.data = data;
        return res;
    }
}

;// ./src/models/response/message.response.ts
class MessageResponse {
    constructor(title, message) {
        this.noColor = false;
        this.object = "message";
        this.title = title;
        this.message = message;
    }
}

;// ./src/auth/commands/lock.command.ts
var lock_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};




class LockCommand {
    constructor(lockService, accountService) {
        this.lockService = lockService;
        this.accountService = accountService;
    }
    run() {
        return lock_command_awaiter(this, void 0, void 0, function* () {
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(account_service_getUserId(this.accountService.activeAccount$));
            yield this.lockService.lock(activeUserId);
            process.env.BW_SESSION = undefined;
            const res = new MessageResponse("Your vault is locked.", null);
            return response_Response.success(res);
        });
    }
}

;// external "http"
const external_http_namespaceObject = require("http");
;// external "inquirer"
const external_inquirer_namespaceObject = require("inquirer");
;// ../../libs/common/src/auth/enums/authentication-type.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var AuthenticationType;
(function (AuthenticationType) {
    AuthenticationType[AuthenticationType["Password"] = 0] = "Password";
    AuthenticationType[AuthenticationType["Sso"] = 1] = "Sso";
    AuthenticationType[AuthenticationType["UserApiKey"] = 2] = "UserApiKey";
    AuthenticationType[AuthenticationType["AuthRequest"] = 3] = "AuthRequest";
    AuthenticationType[AuthenticationType["WebAuthn"] = 4] = "WebAuthn";
})(AuthenticationType || (AuthenticationType = {}));

;// ../../libs/common/src/auth/models/request/identity-token/token-two-factor.request.ts
class TokenTwoFactorRequest {
    constructor(provider = null, token = null, remember = false) {
        this.provider = provider;
        this.token = token;
        this.remember = remember;
    }
}

;// ../../libs/common/src/auth/services/webauthn-login/request/webauthn-login-response.request.ts

class WebAuthnLoginResponseRequest {
    constructor(credential) {
        this.id = credential.id;
        this.rawId = utils_Utils.fromBufferToUrlB64(credential.rawId);
        this.type = credential.type;
        // WARNING: do not add PRF information here by mapping
        // credential.getClientExtensionResults() into the extensions property,
        // as it will be sent to the server (leaking credentials).
        this.extensions = {}; // Extensions are handled client-side
    }
}

;// ../../libs/common/src/auth/services/webauthn-login/request/webauthn-login-assertion-response.request.ts


class WebAuthnLoginAssertionResponseRequest extends WebAuthnLoginResponseRequest {
    constructor(credential) {
        super(credential);
        if (!(credential.response instanceof AuthenticatorAssertionResponse)) {
            throw new Error("Invalid authenticator response");
        }
        this.response = {
            authenticatorData: utils_Utils.fromBufferToUrlB64(credential.response.authenticatorData),
            signature: utils_Utils.fromBufferToUrlB64(credential.response.signature),
            clientDataJSON: utils_Utils.fromBufferToUrlB64(credential.response.clientDataJSON),
            userHandle: utils_Utils.fromBufferToUrlB64(credential.response.userHandle),
        };
    }
    static fromJSON(json) {
        return Object.assign(Object.create(WebAuthnLoginAssertionResponseRequest.prototype), json);
    }
}

;// ../../libs/common/src/platform/enums/encryption-type.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var encryption_type_enum_EncryptionType;
(function (EncryptionType) {
    // Symmetric encryption types
    EncryptionType[EncryptionType["AesCbc256_B64"] = 0] = "AesCbc256_B64";
    // Type 1 was the unused and removed AesCbc128_HmacSha256_B64
    EncryptionType[EncryptionType["AesCbc256_HmacSha256_B64"] = 2] = "AesCbc256_HmacSha256_B64";
    // Cose is the encoding for the key used, but contained can be:
    // - XChaCha20Poly1305
    EncryptionType[EncryptionType["CoseEncrypt0"] = 7] = "CoseEncrypt0";
    // Asymmetric encryption types. These never occur in the same places that the symmetric ones would
    // and can be split out into a separate enum.
    EncryptionType[EncryptionType["Rsa2048_OaepSha256_B64"] = 3] = "Rsa2048_OaepSha256_B64";
    EncryptionType[EncryptionType["Rsa2048_OaepSha1_B64"] = 4] = "Rsa2048_OaepSha1_B64";
    EncryptionType[EncryptionType["Rsa2048_OaepSha256_HmacSha256_B64"] = 5] = "Rsa2048_OaepSha256_HmacSha256_B64";
    EncryptionType[EncryptionType["Rsa2048_OaepSha1_HmacSha256_B64"] = 6] = "Rsa2048_OaepSha1_HmacSha256_B64";
})(encryption_type_enum_EncryptionType || (encryption_type_enum_EncryptionType = {}));
function encryptionTypeToString(encryptionType) {
    if (encryptionType in encryption_type_enum_EncryptionType) {
        return encryption_type_enum_EncryptionType[encryptionType];
    }
    else {
        return "Unknown encryption type " + encryptionType;
    }
}
/** The expected number of parts to a serialized EncString of the given encryption type.
 * For example, an EncString of type AesCbc256_B64 will have 2 parts
 *
 * Example of annotated serialized EncStrings:
 * 0.iv|data
 * 2.iv|data|mac
 * 3.data
 * 4.data
 *
 * @see EncString
 * @see EncryptionType
 * @see EncString.parseEncryptedString
 */
const EXPECTED_NUM_PARTS_BY_ENCRYPTION_TYPE = {
    [encryption_type_enum_EncryptionType.AesCbc256_B64]: 2,
    [encryption_type_enum_EncryptionType.AesCbc256_HmacSha256_B64]: 3,
    [encryption_type_enum_EncryptionType.Rsa2048_OaepSha256_B64]: 1,
    [encryption_type_enum_EncryptionType.Rsa2048_OaepSha1_B64]: 1,
    [encryption_type_enum_EncryptionType.Rsa2048_OaepSha256_HmacSha256_B64]: 2,
    [encryption_type_enum_EncryptionType.Rsa2048_OaepSha1_HmacSha256_B64]: 2,
    [encryption_type_enum_EncryptionType.CoseEncrypt0]: 1,
};

;// ../../libs/common/src/platform/enums/file-upload-type.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var FileUploadType;
(function (FileUploadType) {
    FileUploadType[FileUploadType["Direct"] = 0] = "Direct";
    FileUploadType[FileUploadType["Azure"] = 1] = "Azure";
})(FileUploadType || (FileUploadType = {}));

;// ../../libs/storage-core/src/html-storage-location.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var HtmlStorageLocation;
(function (HtmlStorageLocation) {
    HtmlStorageLocation["Local"] = "local";
    HtmlStorageLocation["Memory"] = "memory";
    HtmlStorageLocation["Session"] = "session";
})(HtmlStorageLocation || (HtmlStorageLocation = {}));

;// ../../libs/storage-core/src/storage.service.ts
class StorageService {
}

;// ../../libs/storage-core/src/memory-storage.service.ts
var memory_storage_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


class MemoryStorageService extends StorageService {
    constructor() {
        super(...arguments);
        this.store = new Map();
        this.updatesSubject = new external_rxjs_namespaceObject.Subject();
    }
    get valuesRequireDeserialization() {
        return false;
    }
    get updates$() {
        return this.updatesSubject.asObservable();
    }
    get(key) {
        if (this.store.has(key)) {
            const obj = this.store.get(key);
            return Promise.resolve(obj);
        }
        return Promise.resolve(null);
    }
    has(key) {
        return memory_storage_service_awaiter(this, void 0, void 0, function* () {
            return (yield this.get(key)) != null;
        });
    }
    save(key, obj) {
        if (obj == null) {
            return this.remove(key);
        }
        // TODO: Remove once foreground/background contexts are separated in browser
        // Needed to ensure ownership of all memory by the context running the storage service
        const toStore = structuredClone(obj);
        this.store.set(key, toStore);
        this.updatesSubject.next({ key, updateType: "save" });
        return Promise.resolve();
    }
    remove(key) {
        this.store.delete(key);
        this.updatesSubject.next({ key, updateType: "remove" });
        return Promise.resolve();
    }
}

;// ../../libs/storage-core/src/serialized-memory-storage.service.ts
var serialized_memory_storage_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


class SerializedMemoryStorageService extends StorageService {
    constructor() {
        super(...arguments);
        this.store = {};
        this.updatesSubject = new external_rxjs_namespaceObject.Subject();
    }
    get valuesRequireDeserialization() {
        return true;
    }
    get updates$() {
        return this.updatesSubject.asObservable();
    }
    get(key) {
        const json = this.store[key];
        if (json) {
            const obj = JSON.parse(json);
            return Promise.resolve(obj);
        }
        return Promise.resolve(null);
    }
    has(key) {
        return serialized_memory_storage_service_awaiter(this, void 0, void 0, function* () {
            return (yield this.get(key)) != null;
        });
    }
    save(key, obj) {
        if (obj == null) {
            return this.remove(key);
        }
        // TODO: Remove once foreground/background contexts are separated in browser
        // Needed to ensure ownership of all memory by the context running the storage service
        this.store[key] = JSON.stringify(obj);
        this.updatesSubject.next({ key, updateType: "save" });
        return Promise.resolve();
    }
    remove(key) {
        delete this.store[key];
        this.updatesSubject.next({ key, updateType: "remove" });
        return Promise.resolve();
    }
}

;// ../../libs/storage-core/src/storage-location.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var StorageLocationEnum;
(function (StorageLocationEnum) {
    StorageLocationEnum["Both"] = "both";
    StorageLocationEnum["Disk"] = "disk";
    StorageLocationEnum["Memory"] = "memory";
})(StorageLocationEnum || (StorageLocationEnum = {}));

;// ../../libs/storage-core/src/storage-service.provider.ts
/**
 * A provider for getting client specific computed storage locations and services.
 */
class StorageServiceProvider {
    constructor(diskStorageService, memoryStorageService) {
        this.diskStorageService = diskStorageService;
        this.memoryStorageService = memoryStorageService;
    }
    /**
     * Computes the location and corresponding service for a given client.
     *
     * **NOTE** The default implementation does not respect client overrides and if clients
     * have special overrides they are responsible for implementing this service.
     * @param defaultLocation The default location to use if no client specific override is preferred.
     * @param overrides Client specific overrides
     * @returns The computed storage location and corresponding storage service to use to get/store state.
     * @throws If there is no configured storage service for the given inputs.
     */
    get(defaultLocation, overrides) {
        switch (defaultLocation) {
            case "disk":
                return [defaultLocation, this.diskStorageService];
            case "memory":
                return [defaultLocation, this.memoryStorageService];
            default:
                throw new Error(`Unexpected location: ${defaultLocation}`);
        }
    }
}

;// ../../libs/storage-core/src/index.ts








// Renamed to just "StorageService", to be removed when references are updated



;// ../../libs/common/src/platform/enums/html-storage-location.enum.ts


;// ../../libs/common/src/platform/enums/key-suffix-options.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var KeySuffixOptions;
(function (KeySuffixOptions) {
    KeySuffixOptions["Auto"] = "auto";
    KeySuffixOptions["Pin"] = "pin";
})(KeySuffixOptions || (KeySuffixOptions = {}));

;// ../../libs/logging/src/log-level.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var LogLevel;
(function (LogLevel) {
    LogLevel[LogLevel["Debug"] = 0] = "Debug";
    LogLevel[LogLevel["Info"] = 1] = "Info";
    LogLevel[LogLevel["Warning"] = 2] = "Warning";
    LogLevel[LogLevel["Error"] = 3] = "Error";
})(LogLevel || (LogLevel = {}));

;// ../../libs/logging/src/console-log.service.ts

class console_log_service_ConsoleLogService {
    constructor(isDev, filter = null) {
        this.isDev = isDev;
        this.filter = filter;
        this.timersMap = new Map();
    }
    debug(message, ...optionalParams) {
        if (!this.isDev) {
            return;
        }
        this.write(LogLevel.Debug, message, ...optionalParams);
    }
    info(message, ...optionalParams) {
        this.write(LogLevel.Info, message, ...optionalParams);
    }
    warning(message, ...optionalParams) {
        this.write(LogLevel.Warning, message, ...optionalParams);
    }
    error(message, ...optionalParams) {
        this.write(LogLevel.Error, message, ...optionalParams);
    }
    write(level, message, ...optionalParams) {
        if (this.filter != null && this.filter(level)) {
            return;
        }
        switch (level) {
            case LogLevel.Debug:
                // eslint-disable-next-line
                console.log(message, ...optionalParams);
                break;
            case LogLevel.Info:
                // eslint-disable-next-line
                console.log(message, ...optionalParams);
                break;
            case LogLevel.Warning:
                // eslint-disable-next-line
                console.warn(message, ...optionalParams);
                break;
            case LogLevel.Error:
                // eslint-disable-next-line
                console.error(message, ...optionalParams);
                break;
            default:
                break;
        }
    }
    measure(start, trackGroup, track, name, properties) {
        const measureName = `[${track}]: ${name}`;
        const measure = performance.measure(measureName, {
            start: start,
            detail: {
                devtools: {
                    dataType: "track-entry",
                    track,
                    trackGroup,
                    properties,
                },
            },
        });
        this.info(`${measureName} took ${measure.duration}`, properties);
        return measure;
    }
    mark(name) {
        const mark = performance.mark(name, {
            detail: {
                devtools: {
                    dataType: "marker",
                },
            },
        });
        this.info(mark.name, new Date().toISOString());
        return mark;
    }
}

;// ../../libs/logging/src/index.ts




;// ../../libs/common/src/platform/enums/log-level-type.enum.ts


;// ../../libs/common/src/platform/enums/storage-location.enum.ts


;// ../../libs/common/src/platform/enums/theme-type.enum.ts
/**
 * @deprecated prefer the `ThemeTypes` constants and `Theme` type over unsafe enum types
 **/
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var ThemeType;
(function (ThemeType) {
    ThemeType["System"] = "system";
    ThemeType["Light"] = "light";
    ThemeType["Dark"] = "dark";
})(ThemeType || (ThemeType = {}));
const ThemeTypes = {
    System: "system",
    Light: "light",
    Dark: "dark",
};

;// ../../libs/common/src/platform/enums/index.ts








;// ../../libs/common/src/platform/models/domain/symmetric-crypto-key.ts


/**
 *  A symmetric crypto key represents a symmetric key usable for symmetric encryption and decryption operations.
 *  The specific algorithm used is private to the key, and should only be exposed to encrypt service implementations.
 *  This can be done via `inner()`.
 */
class SymmetricCryptoKey {
    /**
     * @param key The key in one of the permitted serialization formats
     */
    constructor(key) {
        if (key == null) {
            throw new Error("Must provide key");
        }
        if (key.byteLength === 32) {
            this.innerKey = {
                type: encryption_type_enum_EncryptionType.AesCbc256_B64,
                encryptionKey: key,
            };
            this.keyB64 = this.toBase64();
        }
        else if (key.byteLength === 64) {
            this.innerKey = {
                type: encryption_type_enum_EncryptionType.AesCbc256_HmacSha256_B64,
                encryptionKey: key.slice(0, 32),
                authenticationKey: key.slice(32),
            };
            this.keyB64 = this.toBase64();
        }
        else if (key.byteLength > 64) {
            this.innerKey = {
                type: encryption_type_enum_EncryptionType.CoseEncrypt0,
                encryptionKey: key,
            };
            this.keyB64 = this.toBase64();
        }
        else {
            throw new Error(`Unsupported encType/key length ${key.byteLength}`);
        }
    }
    toJSON() {
        // The whole object is constructed from the initial key, so just store the B64 key
        return { keyB64: this.keyB64 };
    }
    /**
     * It is preferred not to work with the raw key where possible.
     * Only use this method if absolutely necessary.
     *
     * @returns The inner key instance that can be directly used for encryption primitives
     */
    inner() {
        return this.innerKey;
    }
    /**
     * @returns The serialized key in base64 format
     */
    toBase64() {
        return utils_Utils.fromBufferToB64(this.toEncoded());
    }
    /**
     * Serializes the key to a format that can be written to state or shared
     * The currently permitted format is:
     * - AesCbc256_B64: 32 bytes (the raw key)
     * - AesCbc256_HmacSha256_B64: 64 bytes (32 bytes encryption key, 32 bytes authentication key, concatenated)
     *
     * @returns The serialized key that can be written to state or encrypted and then written to state / shared
     */
    toEncoded() {
        if (this.innerKey.type === encryption_type_enum_EncryptionType.AesCbc256_B64) {
            return this.innerKey.encryptionKey;
        }
        else if (this.innerKey.type === encryption_type_enum_EncryptionType.AesCbc256_HmacSha256_B64) {
            const encodedKey = new Uint8Array(64);
            encodedKey.set(this.innerKey.encryptionKey, 0);
            encodedKey.set(this.innerKey.authenticationKey, 32);
            return encodedKey;
        }
        else if (this.innerKey.type === encryption_type_enum_EncryptionType.CoseEncrypt0) {
            return this.innerKey.encryptionKey;
        }
        else {
            throw new Error("Unsupported encryption type.");
        }
    }
    /**
     * @param s The serialized key in base64 format
     * @returns A SymmetricCryptoKey instance
     */
    static fromString(s) {
        if (s == null) {
            return null;
        }
        const arrayBuffer = utils_Utils.fromB64ToArray(s);
        return new SymmetricCryptoKey(arrayBuffer);
    }
    static fromJSON(obj) {
        return SymmetricCryptoKey.fromString(obj === null || obj === void 0 ? void 0 : obj.keyB64);
    }
}

;// ../../libs/auth/src/common/models/domain/login-credentials.ts




class PasswordLoginCredentials {
    constructor(email, masterPassword, twoFactor, masterPasswordPoliciesFromOrgInvite, 
    /** Prefetched prelogin data. If provided, skips the prelogin API call during login. */
    preFetchedPreloginData) {
        this.email = email;
        this.masterPassword = masterPassword;
        this.twoFactor = twoFactor;
        this.masterPasswordPoliciesFromOrgInvite = masterPasswordPoliciesFromOrgInvite;
        this.preFetchedPreloginData = preFetchedPreloginData;
        this.type = AuthenticationType.Password;
    }
}
class SsoLoginCredentials {
    constructor(code, codeVerifier, redirectUrl, orgId, 
    /**
     * Optional email address for SSO login.
     * Used for looking up 2FA token on clients that support remembering 2FA token.
     */
    email, twoFactor) {
        this.code = code;
        this.codeVerifier = codeVerifier;
        this.redirectUrl = redirectUrl;
        this.orgId = orgId;
        this.email = email;
        this.twoFactor = twoFactor;
        this.type = AuthenticationType.Sso;
    }
}
class UserApiLoginCredentials {
    constructor(clientId, clientSecret) {
        this.clientId = clientId;
        this.clientSecret = clientSecret;
        this.type = AuthenticationType.UserApiKey;
    }
}
class AuthRequestLoginCredentials {
    constructor(email, accessCode, authRequestId, decryptedUserKey, twoFactor) {
        this.email = email;
        this.accessCode = accessCode;
        this.authRequestId = authRequestId;
        this.decryptedUserKey = decryptedUserKey;
        this.twoFactor = twoFactor;
        this.type = AuthenticationType.AuthRequest;
    }
    static fromJSON(json) {
        return Object.assign(new AuthRequestLoginCredentials(json.email, json.accessCode, json.authRequestId, null, json.twoFactor
            ? new TokenTwoFactorRequest(json.twoFactor.provider, json.twoFactor.token, json.twoFactor.remember)
            : json.twoFactor), {
            decryptedUserKey: SymmetricCryptoKey.fromJSON(json.decryptedUserKey),
        });
    }
}
class WebAuthnLoginCredentials {
    constructor(token, deviceResponse, prfKey) {
        this.token = token;
        this.deviceResponse = deviceResponse;
        this.prfKey = prfKey;
        this.type = AuthenticationType.WebAuthn;
    }
    static fromJSON(json) {
        return new WebAuthnLoginCredentials(json.token, Object.assign(Object.create(WebAuthnLoginAssertionResponseRequest.prototype), json.deviceResponse), SymmetricCryptoKey.fromJSON(json.prfKey));
    }
}

;// ../../libs/auth/src/common/models/domain/user-decryption-options.ts
/**
 * Key Connector decryption options. Intended to be sent to the client for use after authentication.
 * @see {@link UserDecryptionOptions}
 */
class KeyConnectorUserDecryptionOption {
    /**
     * Initializes a new instance of the KeyConnectorUserDecryptionOption from a response object.
     * @param response The key connector user decryption option response object.
     * @returns A new instance of the KeyConnectorUserDecryptionOption or undefined if `response` is nullish.
     */
    static fromResponse(response) {
        var _a;
        if (response == null) {
            return undefined;
        }
        const options = new KeyConnectorUserDecryptionOption();
        options.keyConnectorUrl = (_a = response === null || response === void 0 ? void 0 : response.keyConnectorUrl) !== null && _a !== void 0 ? _a : null;
        return options;
    }
    /**
     * Initializes a new instance of a KeyConnectorUserDecryptionOption from a JSON object.
     * @param obj JSON object to deserialize.
     * @returns A new instance of the KeyConnectorUserDecryptionOption or undefined if `obj` is nullish.
     */
    static fromJSON(obj) {
        if (obj == null) {
            return undefined;
        }
        return Object.assign(new KeyConnectorUserDecryptionOption(), obj);
    }
}
/**
 * Trusted device decryption options. Intended to be sent to the client for use after authentication.
 * @see {@link UserDecryptionOptions}
 */
/**
 * WebAuthn PRF decryption options. Intended to be sent to the client for use after authentication.
 * @see {@link UserDecryptionOptions}
 */
class WebAuthnPrfUserDecryptionOption {
    /**
     * Initializes a new instance of the WebAuthnPrfUserDecryptionOption from a response object.
     * @param response The WebAuthn PRF user decryption option response object.
     * @returns A new instance of the WebAuthnPrfUserDecryptionOption or undefined if `response` is nullish.
     */
    static fromResponse(response) {
        if (response == null) {
            return undefined;
        }
        if (!response.encryptedPrivateKey || !response.encryptedUserKey) {
            return undefined;
        }
        const options = new WebAuthnPrfUserDecryptionOption();
        options.encryptedPrivateKey = response.encryptedPrivateKey.encryptedString;
        options.encryptedUserKey = response.encryptedUserKey.encryptedString;
        options.credentialId = response.credentialId;
        options.transports = response.transports || [];
        return options;
    }
    /**
     * Initializes a new instance of a WebAuthnPrfUserDecryptionOption from a JSON object.
     * @param obj JSON object to deserialize.
     * @returns A new instance of the WebAuthnPrfUserDecryptionOption or undefined if `obj` is nullish.
     */
    static fromJSON(obj) {
        if (obj == null) {
            return undefined;
        }
        return Object.assign(new WebAuthnPrfUserDecryptionOption(), obj);
    }
}
/**
 * Trusted device decryption options. Intended to be sent to the client for use after authentication.
 * @see {@link UserDecryptionOptions}
 */
class TrustedDeviceUserDecryptionOption {
    /**
     * Initializes a new instance of the TrustedDeviceUserDecryptionOption from a response object.
     * @param response The trusted device user decryption option response object.
     * @returns A new instance of the TrustedDeviceUserDecryptionOption or undefined if `response` is nullish.
     */
    static fromResponse(response) {
        var _a, _b, _c, _d;
        if (response == null) {
            return undefined;
        }
        const options = new TrustedDeviceUserDecryptionOption();
        options.hasAdminApproval = (_a = response === null || response === void 0 ? void 0 : response.hasAdminApproval) !== null && _a !== void 0 ? _a : false;
        options.hasLoginApprovingDevice = (_b = response === null || response === void 0 ? void 0 : response.hasLoginApprovingDevice) !== null && _b !== void 0 ? _b : false;
        options.hasManageResetPasswordPermission = (_c = response === null || response === void 0 ? void 0 : response.hasManageResetPasswordPermission) !== null && _c !== void 0 ? _c : false;
        options.isTdeOffboarding = (_d = response === null || response === void 0 ? void 0 : response.isTdeOffboarding) !== null && _d !== void 0 ? _d : false;
        return options;
    }
    /**
     * Initializes a new instance of the TrustedDeviceUserDecryptionOption from a JSON object.
     * @param obj JSON object to deserialize.
     * @returns A new instance of the TrustedDeviceUserDecryptionOption or undefined if `obj` is nullish.
     */
    static fromJSON(obj) {
        if (obj == null) {
            return undefined;
        }
        return Object.assign(new TrustedDeviceUserDecryptionOption(), obj);
    }
}
/**
 * Represents the decryption options the user has configured on the server. This is intended to be sent
 * to the client on authentication, and can be used to determine how to decrypt the user's vault.
 */
class UserDecryptionOptions {
    /**
     * Initializes a new instance of the UserDecryptionOptions from a response object.
     * @param response user decryption options response object
     * @returns A new instance of the UserDecryptionOptions.
     * @throws If the response is nullish, this method will throw an error. User decryption options
     * are required for client initialization.
     */
    static fromIdentityTokenResponse(response) {
        if (response == null) {
            throw new Error("User Decryption Options are required for client initialization. Response is nullish.");
        }
        const decryptionOptions = new UserDecryptionOptions();
        if (response.userDecryptionOptions) {
            // If the response has userDecryptionOptions, this means it's on a post-TDE server version and can interrogate
            // the new decryption options.
            const responseOptions = response.userDecryptionOptions;
            decryptionOptions.hasMasterPassword = responseOptions.hasMasterPassword;
            decryptionOptions.trustedDeviceOption = TrustedDeviceUserDecryptionOption.fromResponse(responseOptions.trustedDeviceOption);
            decryptionOptions.keyConnectorOption = KeyConnectorUserDecryptionOption.fromResponse(responseOptions.keyConnectorOption);
            // The IdTokenResponse only returns a single WebAuthn PRF option to support immediate unlock after logging in
            // with the same PRF passkey.
            // Since our domain model supports multiple WebAuthn PRF options, we convert the single option into an array.
            if (responseOptions.webAuthnPrfOption) {
                const option = WebAuthnPrfUserDecryptionOption.fromResponse(responseOptions.webAuthnPrfOption);
                if (option) {
                    decryptionOptions.webAuthnPrfOptions = [option];
                }
            }
        }
        else {
            throw new Error("User Decryption Options are required for client initialization. userDecryptionOptions is missing in response.");
        }
        return decryptionOptions;
    }
    /**
     * Initializes a new instance of the UserDecryptionOptions from a JSON object.
     * @param obj JSON object to deserialize.
     * @returns A new instance of the UserDecryptionOptions. Will initialize even if the JSON object is nullish.
     */
    static fromJSON(obj) {
        const decryptionOptions = Object.assign(new UserDecryptionOptions(), obj);
        decryptionOptions.trustedDeviceOption = TrustedDeviceUserDecryptionOption.fromJSON(obj === null || obj === void 0 ? void 0 : obj.trustedDeviceOption);
        decryptionOptions.keyConnectorOption = KeyConnectorUserDecryptionOption.fromJSON(obj === null || obj === void 0 ? void 0 : obj.keyConnectorOption);
        if ((obj === null || obj === void 0 ? void 0 : obj.webAuthnPrfOptions) && Array.isArray(obj.webAuthnPrfOptions)) {
            decryptionOptions.webAuthnPrfOptions = obj.webAuthnPrfOptions
                .map((option) => WebAuthnPrfUserDecryptionOption.fromJSON(option))
                .filter((option) => option !== undefined);
        }
        return decryptionOptions;
    }
}

;// ../../libs/auth/src/common/models/domain/index.ts



;// ../../libs/auth/src/common/models/spec/fake-user-decryption-options.ts

// To discourage creating new user decryption options, we don't expose a constructor.
// These helpers are for testing purposes only.
/** Testing helper for creating new instances of `UserDecryptionOptions` */
class FakeUserDecryptionOptions extends UserDecryptionOptions {
    constructor(init) {
        super();
        Object.assign(this, init);
    }
}
/** Testing helper for creating new instances of `KeyConnectorUserDecryptionOption` */
class FakeKeyConnectorUserDecryptionOption extends KeyConnectorUserDecryptionOption {
    constructor(keyConnectorUrl) {
        super();
        this.keyConnectorUrl = keyConnectorUrl;
    }
}
/** Testing helper for creating new instances of `TrustedDeviceUserDecryptionOption` */
class FakeTrustedDeviceUserDecryptionOption extends TrustedDeviceUserDecryptionOption {
    constructor(hasAdminApproval, hasLoginApprovingDevice, hasManageResetPasswordPermission, isTdeOffboarding) {
        super();
        this.hasAdminApproval = hasAdminApproval;
        this.hasLoginApprovingDevice = hasLoginApprovingDevice;
        this.hasManageResetPasswordPermission = hasManageResetPasswordPermission;
        this.isTdeOffboarding = isTdeOffboarding;
    }
}

;// ../../libs/auth/src/common/models/spec/index.ts


;// ../../libs/auth/src/common/models/index.ts



;// ../../libs/auth/src/common/services/login-email/login-email.service.ts
var login_email_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};


// FIXME: remove `src` and fix import
// eslint-disable-next-line no-restricted-imports

const LOGIN_EMAIL = new KeyDefinition(LOGIN_EMAIL_MEMORY, "loginEmail", {
    deserializer: (value) => value,
});
const login_email_service_STORED_EMAIL = new KeyDefinition(LOGIN_EMAIL_DISK, "storedEmail", {
    deserializer: (value) => value,
});
class LoginEmailService {
    constructor(accountService, authService, stateProvider) {
        this.accountService = accountService;
        this.authService = authService;
        this.stateProvider = stateProvider;
        this.loginEmailState = this.stateProvider.getGlobal(LOGIN_EMAIL);
        this.storedEmailState = this.stateProvider.getGlobal(login_email_service_STORED_EMAIL);
        // In order to determine if an account is being added, we check if any account is not logged out
        this.addingAccount$ = this.authService.authStatuses$.pipe(switchMap((statuses) => login_email_service_awaiter(this, void 0, void 0, function* () {
            // We don't want to consider the active account since it may have just changed auth status to logged in
            // which would make this observable think an account is being added
            const activeUser = yield firstValueFrom(this.accountService.activeAccount$);
            if (activeUser) {
                delete statuses[activeUser.id];
            }
            return Object.values(statuses).some((status) => status !== AuthenticationStatus.LoggedOut);
        })));
        this.loginEmail$ = this.loginEmailState.state$;
        this.rememberedEmail$ = this.storedEmailState.state$.pipe(switchMap((storedEmail) => login_email_service_awaiter(this, void 0, void 0, function* () {
            // When adding an account, we don't show the stored email
            if (yield firstValueFrom(this.addingAccount$)) {
                return null;
            }
            return storedEmail;
        })));
    }
    /** Sets the login email in memory.
     * The login email is the email that is being used in the current login process.
     */
    setLoginEmail(email) {
        return login_email_service_awaiter(this, void 0, void 0, function* () {
            yield this.loginEmailState.update((_) => email);
        });
    }
    /**
     * Clears the in-progress login email from state.
     * Note: Only clear on successful login or you are sure they are not needed.
     * The extension client uses these values to maintain the email between login and 2fa components so
     * we do not want to clear them too early.
     */
    clearLoginEmail() {
        return login_email_service_awaiter(this, void 0, void 0, function* () {
            yield this.loginEmailState.update((_) => null);
        });
    }
    setRememberedEmailChoice(email, remember) {
        return login_email_service_awaiter(this, void 0, void 0, function* () {
            if (remember) {
                yield this.storedEmailState.update((_) => email);
            }
            else {
                yield this.storedEmailState.update((_) => null);
            }
        });
    }
    clearRememberedEmail() {
        return login_email_service_awaiter(this, void 0, void 0, function* () {
            yield this.storedEmailState.update((_) => null);
        });
    }
}

;// ../../libs/common/src/auth/models/request/identity-token/device.request.ts
class DeviceRequest {
    constructor(appId, platformUtilsService) {
        this.type = platformUtilsService.getDevice();
        this.name = platformUtilsService.getDeviceString();
        this.identifier = appId;
        this.pushToken = null;
    }
    static fromJSON(json) {
        return Object.assign(Object.create(DeviceRequest.prototype), json);
    }
}

;// ../../libs/common/src/auth/models/request/identity-token/token.request.ts
class TokenRequest {
    constructor(twoFactor, device) {
        this.twoFactor = twoFactor;
        this.device = device != null ? device : null;
    }
    setTwoFactor(twoFactor) {
        this.twoFactor = twoFactor;
    }
    setAuthRequestAccessCode(accessCode) {
        this.authRequest = accessCode;
    }
    toIdentityToken(clientId) {
        const obj = {
            scope: "api offline_access",
            client_id: clientId,
        };
        if (this.device) {
            obj.deviceType = this.device.type;
            obj.deviceIdentifier = this.device.identifier;
            obj.deviceName = this.device.name;
            // no push tokens for browser apps yet
            // obj.devicePushToken = this.device.pushToken;
        }
        //passswordless login
        if (this.authRequest) {
            obj.authRequest = this.authRequest;
        }
        if (this.twoFactor) {
            if (this.twoFactor.token && this.twoFactor.provider != null) {
                obj.twoFactorToken = this.twoFactor.token;
                obj.twoFactorProvider = this.twoFactor.provider;
                obj.twoFactorRemember = this.twoFactor.remember ? "1" : "0";
            }
        }
        return obj;
    }
}

;// ../../libs/common/src/auth/models/request/identity-token/password-token.request.ts



class PasswordTokenRequest extends TokenRequest {
    constructor(email, masterPasswordHash, twoFactor, device, newDeviceOtp) {
        super(twoFactor, device);
        this.email = email;
        this.masterPasswordHash = masterPasswordHash;
        this.twoFactor = twoFactor;
        this.newDeviceOtp = newDeviceOtp;
    }
    toIdentityToken(clientId) {
        const obj = super.toIdentityToken(clientId);
        obj.grant_type = "password";
        obj.username = this.email;
        obj.password = this.masterPasswordHash;
        if (this.newDeviceOtp) {
            obj.newDeviceOtp = this.newDeviceOtp;
        }
        return obj;
    }
    static fromJSON(json) {
        return Object.assign(Object.create(PasswordTokenRequest.prototype), json, {
            device: json.device ? DeviceRequest.fromJSON(json.device) : undefined,
            twoFactor: json.twoFactor
                ? Object.assign(new TokenTwoFactorRequest(), json.twoFactor)
                : undefined,
        });
    }
}

;// ../../libs/common/src/auth/enums/two-factor-provider-type.ts
const TwoFactorProviderType = Object.freeze({
    Authenticator: 0,
    Email: 1,
    Duo: 2,
    Yubikey: 3,
    // U2f: 4, - deprecated in favor of WebAuthn
    Remember: 5,
    OrganizationDuo: 6,
    WebAuthn: 7,
    RecoveryCode: 8,
});
/**
 * Type guard that checks whether an unknown value is a valid {@link TwoFactorProviderType}.
 *
 * Useful for validating untrusted input (e.g. parsed integers from CLI arguments or API
 * responses) before assigning it to a typed variable.
 *
 * @param value - The value to test.
 * @returns `true` if `value` is one of the known {@link TwoFactorProviderType} values, narrowing
 * the type accordingly.
 *
 * @example
 * const parsed = parseInt(raw, 10);
 * if (isTwoFactorProviderType(parsed)) {
 *   // parsed is TwoFactorProviderType here
 * }
 */
function isTwoFactorProviderType(value) {
    return Object.values(TwoFactorProviderType).includes(value);
}

;// ../../libs/common/src/auth/models/domain/auth-result.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

class AuthResult {
    constructor() {
        this.twoFactorProviders = null;
    }
    get requiresTwoFactor() {
        return this.twoFactorProviders != null;
    }
    // This is not as extensible as an object-based approach. In the future we may need to adjust to an object based approach.
    get requiresSso() {
        return !utils_Utils.isNullOrWhitespace(this.ssoOrganizationIdentifier);
    }
}

;// ../../libs/common/src/auth/models/domain/force-set-password-reason.ts
/**
 * This enum is used to determine if a user should be forced to set an initial password or
 * change their existing password upon login (communicated via server flag) or upon unlocking
 * with their master password (set via client evaluation).
 */
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var ForceSetPasswordReason;
(function (ForceSetPasswordReason) {
    /**
     * A password set/change should not be forced.
     */
    ForceSetPasswordReason[ForceSetPasswordReason["None"] = 0] = "None";
    /*--------------------------
        Set Initial Password
    ---------------------------*/
    /**
     * Occurs when a user JIT provisions into a master-password-encryption org via SSO and must set their initial password.
     */
    ForceSetPasswordReason[ForceSetPasswordReason["SsoNewJitProvisionedUser"] = 1] = "SsoNewJitProvisionedUser";
    /**
     * Occurs when a TDE org user without a password obtains the password reset ("manage account recovery")
     * permission, which requires the TDE user to have/set a password.
     *
     * Set post login & decryption client side and by server in sync (to catch logged in users).
     */
    ForceSetPasswordReason[ForceSetPasswordReason["TdeUserWithoutPasswordHasPasswordResetPermission"] = 2] = "TdeUserWithoutPasswordHasPasswordResetPermission";
    /**
     * Occurs when an org admin switches the org from trusted-device-encryption to master-password-encryption,
     * which forces the org user to set an initial password. User must not already have a master password,
     * and they must be on a previously trusted device.
     *
     * Communicated via server flag.
     */
    ForceSetPasswordReason[ForceSetPasswordReason["TdeOffboarding"] = 3] = "TdeOffboarding";
    /**
     * Occurs when an org admin switches the org from trusted-device-encryption to master-password-encryption,
     * which forces the org user to set an initial password. User must not already have a master password,
     * and they must be on an untrusted device.
     *
     * Calculated on client based on server flags and user state.
     */
    ForceSetPasswordReason[ForceSetPasswordReason["TdeOffboardingUntrustedDevice"] = 4] = "TdeOffboardingUntrustedDevice";
    /*----------------------------
        Change Existing Password
    -----------------------------*/
    /**
     * Occurs when an org admin forces a user to change their password via Account Recovery.
     *
     * Communicated via server flag.
     */
    ForceSetPasswordReason[ForceSetPasswordReason["AdminForcePasswordReset"] = 5] = "AdminForcePasswordReset";
    /**
     * Occurs when a user logs in / unlocks their vault with a master password that does not meet an org's
     * master password policy that is enforced on login/unlock.
     *
     * Only set client side b/c server can't evaluate MP.
     */
    ForceSetPasswordReason[ForceSetPasswordReason["WeakMasterPassword"] = 6] = "WeakMasterPassword";
})(ForceSetPasswordReason || (ForceSetPasswordReason = {}));

;// ../../libs/common/src/auth/models/response/identity-device-verification.response.ts

class IdentityDeviceVerificationResponse extends BaseResponse {
    constructor(response) {
        var _a;
        super(response);
        this.deviceVerified = (_a = this.getResponseProperty("DeviceVerified")) !== null && _a !== void 0 ? _a : false;
    }
}

;// ../../libs/common/src/auth/models/response/identity-sso-required.response.ts

class IdentitySsoRequiredResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.ssoOrganizationIdentifier = this.getResponseProperty("SsoOrganizationIdentifier");
    }
}

;// ../../libs/common/src/key-management/crypto/models/enc-string.ts


const DECRYPT_ERROR = "[error: cannot decrypt]";
class enc_string_EncString {
    constructor(encryptedStringOrType, 
    /** @deprecated */
    data, 
    /** @deprecated */
    iv, 
    /** @deprecated */
    mac) {
        if (data != null) {
            this.initFromData(encryptedStringOrType, data, iv, mac);
        }
        else {
            this.initFromEncryptedString(encryptedStringOrType);
        }
    }
    /** @deprecated */
    get ivBytes() {
        return this.iv == null ? null : utils_Utils.fromB64ToArray(this.iv);
    }
    /** @deprecated */
    get macBytes() {
        return this.mac == null ? null : utils_Utils.fromB64ToArray(this.mac);
    }
    /** @deprecated */
    get dataBytes() {
        return this.data == null ? null : utils_Utils.fromB64ToArray(this.data);
    }
    toSdk() {
        return this.encryptedString;
    }
    toJSON() {
        return this.encryptedString;
    }
    static fromJSON(obj) {
        if (obj == null) {
            return null;
        }
        return new enc_string_EncString(obj);
    }
    /** @deprecated */
    initFromData(encType, data, iv, mac) {
        if (iv != null) {
            this.encryptedString = (encType + "." + iv + "|" + data);
        }
        else {
            this.encryptedString = (encType + "." + data);
        }
        // mac
        if (mac != null) {
            this.encryptedString = (this.encryptedString + "|" + mac);
        }
        this.encryptionType = encType;
        this.data = data;
        this.iv = iv;
        this.mac = mac;
    }
    initFromEncryptedString(encryptedString) {
        this.encryptedString = encryptedString;
        if (!this.encryptedString) {
            return;
        }
        const { encType, encPieces } = enc_string_EncString.parseEncryptedString(this.encryptedString);
        this.encryptionType = encType;
        if (encPieces.length !== EXPECTED_NUM_PARTS_BY_ENCRYPTION_TYPE[encType]) {
            return;
        }
        switch (encType) {
            case encryption_type_enum_EncryptionType.AesCbc256_HmacSha256_B64:
                this.iv = encPieces[0];
                this.data = encPieces[1];
                this.mac = encPieces[2];
                break;
            case encryption_type_enum_EncryptionType.AesCbc256_B64:
                this.iv = encPieces[0];
                this.data = encPieces[1];
                break;
            case encryption_type_enum_EncryptionType.Rsa2048_OaepSha256_B64:
            case encryption_type_enum_EncryptionType.Rsa2048_OaepSha1_B64:
                this.data = encPieces[0];
                break;
            case encryption_type_enum_EncryptionType.Rsa2048_OaepSha256_HmacSha256_B64:
            case encryption_type_enum_EncryptionType.Rsa2048_OaepSha1_HmacSha256_B64:
                this.data = encPieces[0];
                this.mac = encPieces[1];
                break;
            default:
                return;
        }
    }
    static parseEncryptedString(encryptedString) {
        const headerPieces = encryptedString.split(".");
        let encType;
        let encPieces = null;
        if (headerPieces.length === 2) {
            try {
                encType = parseInt(headerPieces[0], null);
                encPieces = headerPieces[1].split("|");
                // FIXME: Remove when updating file. Eslint update
                // eslint-disable-next-line @typescript-eslint/no-unused-vars
            }
            catch (e) {
                return { encType: NaN, encPieces: [] };
            }
        }
        else {
            encPieces = encryptedString.split("|");
            encType = encryption_type_enum_EncryptionType.AesCbc256_B64;
        }
        return {
            encType,
            encPieces,
        };
    }
    static isSerializedEncString(s) {
        if (s == null) {
            return false;
        }
        const { encType, encPieces } = this.parseEncryptedString(s);
        if (isNaN(encType) || encPieces.length === 0) {
            return false;
        }
        return EXPECTED_NUM_PARTS_BY_ENCRYPTION_TYPE[encType] === encPieces.length;
    }
}

;// ../../libs/key-management/src/biometrics/biometric.state.ts

/**
 * Indicates whether the user elected to store a biometric key to unlock their vault.
 */
const biometric_state_BIOMETRIC_UNLOCK_ENABLED = new UserKeyDefinition(BIOMETRIC_SETTINGS_DISK, "biometricUnlockEnabled", {
    deserializer: (obj) => obj,
    clearOn: [],
});
/**
 * If the user has elected to require a password on first unlock of an application instance, this key will store the
 * encrypted client key half used to unlock the vault.
 *
 * For operating systems without application-level key storage, this key half is concatenated with a signature
 * provided by the OS and used to encrypt the biometric key prior to storage.
 */
const ENCRYPTED_CLIENT_KEY_HALF = new UserKeyDefinition(BIOMETRIC_SETTINGS_DISK, "clientKeyHalf", {
    deserializer: (obj) => obj,
    clearOn: ["logout"],
});
/**
 * Stores whether the user has elected to cancel the biometric prompt. This is stored on disk due to process-reload
 * wiping memory state. We don't want to prompt the user again if they've elected to cancel.
 */
const biometric_state_PROMPT_CANCELLED = KeyDefinition.record(BIOMETRIC_SETTINGS_DISK, "promptCancelled", {
    deserializer: (obj) => obj,
});
/**
 * Stores whether the user has elected to automatically prompt for biometric unlock on application start.
 */
const biometric_state_PROMPT_AUTOMATICALLY = new UserKeyDefinition(BIOMETRIC_SETTINGS_DISK, "promptAutomatically", {
    deserializer: (obj) => obj,
    clearOn: [],
});
/**
 * Stores whether or not IPC handshake has been validated this session.
 */
const FINGERPRINT_VALIDATED = new KeyDefinition(BIOMETRIC_SETTINGS_DISK, "fingerprintValidated", {
    deserializer: (obj) => obj,
});
/**
 * Last process reload time
 */
const LAST_PROCESS_RELOAD = new KeyDefinition(BIOMETRIC_SETTINGS_DISK, "lastProcessReload", {
    deserializer: (obj) => new Date(obj),
});

;// ../../libs/key-management/src/biometrics/biometric-state.service.ts
var biometric_state_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};



class BiometricStateService {
}
class DefaultBiometricStateService {
    constructor(stateProvider) {
        this.stateProvider = stateProvider;
        this.biometricUnlockEnabledState = this.stateProvider.getActive(biometric_state_BIOMETRIC_UNLOCK_ENABLED);
        this.encryptedClientKeyHalfState = this.stateProvider.getActive(ENCRYPTED_CLIENT_KEY_HALF);
        this.encryptedClientKeyHalf$ = this.encryptedClientKeyHalfState.state$.pipe((0,external_rxjs_namespaceObject.map)(encryptedClientKeyHalfToEncString));
        this.promptCancelledState = this.stateProvider.getGlobal(biometric_state_PROMPT_CANCELLED);
        this.promptCancelled$ = (0,external_rxjs_namespaceObject.combineLatest)([
            this.stateProvider.activeUserId$,
            this.promptCancelledState.state$,
        ]).pipe((0,external_rxjs_namespaceObject.map)(([userId, record]) => {
            var _a;
            return userId != null ? ((_a = record === null || record === void 0 ? void 0 : record[userId]) !== null && _a !== void 0 ? _a : false) : false;
        }));
        this.promptAutomaticallyState = this.stateProvider.getActive(biometric_state_PROMPT_AUTOMATICALLY);
        this.promptAutomatically$ = this.promptAutomaticallyState.state$.pipe((0,external_rxjs_namespaceObject.map)(Boolean));
        this.fingerprintValidatedState = this.stateProvider.getGlobal(FINGERPRINT_VALIDATED);
        this.fingerprintValidated$ = this.fingerprintValidatedState.state$.pipe((0,external_rxjs_namespaceObject.map)(Boolean));
        this.lastProcessReloadState = this.stateProvider.getGlobal(LAST_PROCESS_RELOAD);
        this.lastProcessReload$ = this.lastProcessReloadState.state$;
    }
    setBiometricUnlockEnabled(enabled) {
        return biometric_state_service_awaiter(this, void 0, void 0, function* () {
            yield this.biometricUnlockEnabledState.update(() => enabled);
        });
    }
    biometricUnlockEnabled$(userId) {
        if (userId != null) {
            return this.stateProvider.getUser(userId, biometric_state_BIOMETRIC_UNLOCK_ENABLED).state$.pipe((0,external_rxjs_namespaceObject.map)(Boolean));
        }
        // Backwards compatibility for active user state
        // TODO remove with https://bitwarden.atlassian.net/browse/PM-12043
        return this.biometricUnlockEnabledState.state$.pipe((0,external_rxjs_namespaceObject.map)(Boolean));
    }
    getBiometricUnlockEnabled(userId) {
        return biometric_state_service_awaiter(this, void 0, void 0, function* () {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.stateProvider.getUser(userId, biometric_state_BIOMETRIC_UNLOCK_ENABLED).state$.pipe((0,external_rxjs_namespaceObject.map)(Boolean)));
        });
    }
    setEncryptedClientKeyHalf(encryptedKeyHalf, userId) {
        return biometric_state_service_awaiter(this, void 0, void 0, function* () {
            var _a;
            const value = (_a = encryptedKeyHalf === null || encryptedKeyHalf === void 0 ? void 0 : encryptedKeyHalf.encryptedString) !== null && _a !== void 0 ? _a : null;
            if (userId) {
                yield this.stateProvider.getUser(userId, ENCRYPTED_CLIENT_KEY_HALF).update(() => value);
            }
            else {
                yield this.encryptedClientKeyHalfState.update(() => value);
            }
        });
    }
    getEncryptedClientKeyHalf(userId) {
        return biometric_state_service_awaiter(this, void 0, void 0, function* () {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.stateProvider
                .getUser(userId, ENCRYPTED_CLIENT_KEY_HALF)
                .state$.pipe((0,external_rxjs_namespaceObject.map)(encryptedClientKeyHalfToEncString)));
        });
    }
    logout(userId) {
        return biometric_state_service_awaiter(this, void 0, void 0, function* () {
            yield this.stateProvider.getUser(userId, ENCRYPTED_CLIENT_KEY_HALF).update(() => null);
            yield this.resetUserPromptCancelled(userId);
            // Persist auto prompt setting through logout
            // Persist dismissed require password on start callout through logout
        });
    }
    resetUserPromptCancelled(userId) {
        return biometric_state_service_awaiter(this, void 0, void 0, function* () {
            yield this.stateProvider.getGlobal(biometric_state_PROMPT_CANCELLED).update((data, activeUserId) => {
                if (data != null) {
                    delete data[userId !== null && userId !== void 0 ? userId : activeUserId];
                }
                return data;
            }, {
                combineLatestWith: this.stateProvider.activeUserId$,
                shouldUpdate: (data, activeUserId) => (data === null || data === void 0 ? void 0 : data[userId !== null && userId !== void 0 ? userId : activeUserId]) != null,
            });
        });
    }
    setUserPromptCancelled() {
        return biometric_state_service_awaiter(this, void 0, void 0, function* () {
            yield this.promptCancelledState.update((record, userId) => {
                if (userId != null) {
                    record !== null && record !== void 0 ? record : (record = {});
                    record[userId] = true;
                }
                return record;
            }, {
                combineLatestWith: this.stateProvider.activeUserId$,
                shouldUpdate: (_, userId) => {
                    if (userId == null) {
                        throw new Error("Cannot update biometric prompt cancelled state without an active user");
                    }
                    return true;
                },
            });
        });
    }
    resetAllPromptCancelled() {
        return biometric_state_service_awaiter(this, void 0, void 0, function* () {
            yield this.promptCancelledState.update(() => null);
        });
    }
    setPromptAutomatically(prompt) {
        return biometric_state_service_awaiter(this, void 0, void 0, function* () {
            yield this.promptAutomaticallyState.update(() => prompt);
        });
    }
    setFingerprintValidated(validated) {
        return biometric_state_service_awaiter(this, void 0, void 0, function* () {
            yield this.fingerprintValidatedState.update(() => validated);
        });
    }
    updateLastProcessReload() {
        return biometric_state_service_awaiter(this, void 0, void 0, function* () {
            yield this.lastProcessReloadState.update(() => new Date());
        });
    }
    getLastProcessReload() {
        return biometric_state_service_awaiter(this, void 0, void 0, function* () {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.lastProcessReload$);
        });
    }
}
function encryptedClientKeyHalfToEncString(encryptedKeyHalf) {
    return encryptedKeyHalf == null ? null : new enc_string_EncString(encryptedKeyHalf);
}

;// ../../libs/key-management/src/biometrics/biometrics-status.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var BiometricsStatus;
(function (BiometricsStatus) {
    /** For the biometrics interface, this means that biometric unlock is available and can be used. Querying for the user specifically, this means that biometric can be used for to unlock this user */
    BiometricsStatus[BiometricsStatus["Available"] = 0] = "Available";
    /** Biometrics cannot be used, because the userkey needs to first be unlocked by the user's password, because unlock needs some volatile data that is not available on app-start */
    BiometricsStatus[BiometricsStatus["UnlockNeeded"] = 1] = "UnlockNeeded";
    /** Biometric hardware is not available (i.e laptop folded shut, sensor unplugged) */
    BiometricsStatus[BiometricsStatus["HardwareUnavailable"] = 2] = "HardwareUnavailable";
    /** Only relevant for linux, this means that polkit policies need to be set up and that can happen automatically */
    BiometricsStatus[BiometricsStatus["AutoSetupNeeded"] = 3] = "AutoSetupNeeded";
    /** Only relevant for linux, this means that polkit policies need to be set up but that needs to be done manually */
    BiometricsStatus[BiometricsStatus["ManualSetupNeeded"] = 4] = "ManualSetupNeeded";
    /** Biometrics is not implemented for this platform (i.e web) */
    BiometricsStatus[BiometricsStatus["PlatformUnsupported"] = 5] = "PlatformUnsupported";
    /** Browser extension cannot connect to the desktop app to use biometrics */
    BiometricsStatus[BiometricsStatus["DesktopDisconnected"] = 6] = "DesktopDisconnected";
    /** Biometrics is not enabled in the desktop app/extension (current app) */
    BiometricsStatus[BiometricsStatus["NotEnabledLocally"] = 7] = "NotEnabledLocally";
    /** Only on browser extension; Biometrics is not enabled in the desktop app */
    BiometricsStatus[BiometricsStatus["NotEnabledInConnectedDesktopApp"] = 8] = "NotEnabledInConnectedDesktopApp";
    /** Browser extension does not have the permission to talk to the desktop app */
    BiometricsStatus[BiometricsStatus["NativeMessagingPermissionMissing"] = 9] = "NativeMessagingPermissionMissing";
})(BiometricsStatus || (BiometricsStatus = {}));

;// ../../libs/key-management/src/biometrics/biometrics-commands.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var BiometricsCommands;
(function (BiometricsCommands) {
    /** Perform biometric authentication for the system's user. Does not require setup, and does not return cryptographic material, only yes or no. */
    BiometricsCommands["AuthenticateWithBiometrics"] = "authenticateWithBiometrics";
    /** Get biometric status of the system, and can be used before biometrics is set up. Only returns data about the biometrics system, not about availability of cryptographic material */
    BiometricsCommands["GetBiometricsStatus"] = "getBiometricsStatus";
    /** Perform biometric authentication for the system's user for the given bitwarden account's credentials. This returns cryptographic material that can be used to unlock the vault. */
    BiometricsCommands["UnlockWithBiometricsForUser"] = "unlockWithBiometricsForUser";
    /** Get biometric status for a specific user account. This includes both information about availability of cryptographic material (is the user configured for biometric unlock? is a masterpassword unlock needed? But also information about the biometric system's availability in a single status) */
    BiometricsCommands["GetBiometricsStatusForUser"] = "getBiometricsStatusForUser";
    /** Checks whether the biometric unlock can be enabled. */
    BiometricsCommands["CanEnableBiometricUnlock"] = "canEnableBiometricUnlock";
})(BiometricsCommands || (BiometricsCommands = {}));

;// ../../libs/key-management/src/biometrics/biometric.service.ts
/**
 * The biometrics service is used to provide access to the status of and access to biometric functionality on the platforms.
 */
class BiometricsService {
    supportsBiometric() {
        throw new Error("Method not implemented.");
    }
}

;// ../../libs/key-management/src/abstractions/key.service.ts
class UserPrivateKeyDecryptionFailedError extends Error {
    constructor() {
        super("Failed to decrypt the user's private key.");
    }
}
class KeyService {
}

;// external "big-integer"
const external_big_integer_namespaceObject = require("big-integer");
;// ../../libs/client-type/src/index.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var src_ClientType;
(function (ClientType) {
    ClientType["Web"] = "web";
    ClientType["Browser"] = "browser";
    ClientType["Desktop"] = "desktop";
    // Mobile = "mobile",
    ClientType["Cli"] = "cli";
    // DirectoryConnector = "connector",
})(src_ClientType || (src_ClientType = {}));

;// ../../libs/common/src/admin-console/models/domain/encrypted-organization-key.ts
var encrypted_organization_key_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

class BaseEncryptedOrganizationKey {
    static fromData(data) {
        switch (data.type) {
            case "organization":
                return new EncryptedOrganizationKey(data.key);
            case "provider":
                return new ProviderEncryptedOrganizationKey(data.key, data.providerId);
            default:
                return null;
        }
    }
    static isProviderEncrypted(key) {
        return key.toData().type === "provider";
    }
}
class EncryptedOrganizationKey {
    constructor(key) {
        this.key = key;
    }
    decrypt(encryptService, privateKey) {
        return encrypted_organization_key_awaiter(this, void 0, void 0, function* () {
            return (yield encryptService.decapsulateKeyUnsigned(this.encryptedOrganizationKey, privateKey));
        });
    }
    get encryptedOrganizationKey() {
        return new enc_string_EncString(this.key);
    }
    toData() {
        return {
            type: "organization",
            key: this.key,
        };
    }
}
class ProviderEncryptedOrganizationKey {
    constructor(key, providerId) {
        this.key = key;
        this.providerId = providerId;
    }
    decrypt(encryptService, providerKeys) {
        return encrypted_organization_key_awaiter(this, void 0, void 0, function* () {
            const decValue = yield encryptService.unwrapSymmetricKey(new enc_string_EncString(this.key), providerKeys[this.providerId]);
            if (decValue == null) {
                throw new Error("Failed to decrypt organization key");
            }
            return decValue;
        });
    }
    get encryptedOrganizationKey() {
        return new enc_string_EncString(this.key);
    }
    toData() {
        return {
            type: "provider",
            key: this.key,
            providerId: this.providerId,
        };
    }
}

;// ../../libs/common/src/admin-console/enums/organization-api-key-type.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var OrganizationApiKeyType;
(function (OrganizationApiKeyType) {
    OrganizationApiKeyType[OrganizationApiKeyType["Default"] = 0] = "Default";
    OrganizationApiKeyType[OrganizationApiKeyType["BillingSync"] = 1] = "BillingSync";
    OrganizationApiKeyType[OrganizationApiKeyType["Scim"] = 2] = "Scim";
})(OrganizationApiKeyType || (OrganizationApiKeyType = {}));

;// ../../libs/common/src/admin-console/enums/organization-connection-type.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var OrganizationConnectionType;
(function (OrganizationConnectionType) {
    OrganizationConnectionType[OrganizationConnectionType["CloudBillingSync"] = 1] = "CloudBillingSync";
    OrganizationConnectionType[OrganizationConnectionType["Scim"] = 2] = "Scim";
})(OrganizationConnectionType || (OrganizationConnectionType = {}));

;// ../../libs/common/src/admin-console/enums/organization-user-status-type.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var organization_user_status_type_enum_OrganizationUserStatusType;
(function (OrganizationUserStatusType) {
    OrganizationUserStatusType[OrganizationUserStatusType["Invited"] = 0] = "Invited";
    OrganizationUserStatusType[OrganizationUserStatusType["Accepted"] = 1] = "Accepted";
    OrganizationUserStatusType[OrganizationUserStatusType["Confirmed"] = 2] = "Confirmed";
    OrganizationUserStatusType[OrganizationUserStatusType["Revoked"] = -1] = "Revoked";
})(organization_user_status_type_enum_OrganizationUserStatusType || (organization_user_status_type_enum_OrganizationUserStatusType = {}));

;// ../../libs/common/src/admin-console/enums/organization-user-type.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var organization_user_type_enum_OrganizationUserType;
(function (OrganizationUserType) {
    OrganizationUserType[OrganizationUserType["Owner"] = 0] = "Owner";
    OrganizationUserType[OrganizationUserType["Admin"] = 1] = "Admin";
    OrganizationUserType[OrganizationUserType["User"] = 2] = "User";
    // Manager = 3 has been intentionally permanently deleted
    OrganizationUserType[OrganizationUserType["Custom"] = 4] = "Custom";
})(organization_user_type_enum_OrganizationUserType || (organization_user_type_enum_OrganizationUserType = {}));

;// ../../libs/common/src/admin-console/enums/policy-type.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var policy_type_enum_PolicyType;
(function (PolicyType) {
    PolicyType[PolicyType["TwoFactorAuthentication"] = 0] = "TwoFactorAuthentication";
    PolicyType[PolicyType["MasterPassword"] = 1] = "MasterPassword";
    PolicyType[PolicyType["PasswordGenerator"] = 2] = "PasswordGenerator";
    PolicyType[PolicyType["SingleOrg"] = 3] = "SingleOrg";
    PolicyType[PolicyType["RequireSso"] = 4] = "RequireSso";
    PolicyType[PolicyType["OrganizationDataOwnership"] = 5] = "OrganizationDataOwnership";
    PolicyType[PolicyType["DisableSend"] = 6] = "DisableSend";
    PolicyType[PolicyType["SendOptions"] = 7] = "SendOptions";
    PolicyType[PolicyType["ResetPassword"] = 8] = "ResetPassword";
    PolicyType[PolicyType["MaximumVaultTimeout"] = 9] = "MaximumVaultTimeout";
    PolicyType[PolicyType["DisablePersonalVaultExport"] = 10] = "DisablePersonalVaultExport";
    PolicyType[PolicyType["ActivateAutofill"] = 11] = "ActivateAutofill";
    PolicyType[PolicyType["AutomaticAppLogIn"] = 12] = "AutomaticAppLogIn";
    PolicyType[PolicyType["FreeFamiliesSponsorshipPolicy"] = 13] = "FreeFamiliesSponsorshipPolicy";
    PolicyType[PolicyType["RemoveUnlockWithPin"] = 14] = "RemoveUnlockWithPin";
    PolicyType[PolicyType["RestrictedItemTypes"] = 15] = "RestrictedItemTypes";
    PolicyType[PolicyType["UriMatchDefaults"] = 16] = "UriMatchDefaults";
    PolicyType[PolicyType["AutotypeDefaultSetting"] = 17] = "AutotypeDefaultSetting";
    PolicyType[PolicyType["AutoConfirm"] = 18] = "AutoConfirm";
    PolicyType[PolicyType["BlockClaimedDomainAccountCreation"] = 19] = "BlockClaimedDomainAccountCreation";
    PolicyType[PolicyType["SendControls"] = 21] = "SendControls";
})(policy_type_enum_PolicyType || (policy_type_enum_PolicyType = {}));

;// ../../libs/common/src/admin-console/enums/provider-type.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var provider_type_enum_ProviderType;
(function (ProviderType) {
    ProviderType[ProviderType["Msp"] = 0] = "Msp";
    ProviderType[ProviderType["Reseller"] = 1] = "Reseller";
    ProviderType[ProviderType["BusinessUnit"] = 2] = "BusinessUnit";
})(provider_type_enum_ProviderType || (provider_type_enum_ProviderType = {}));

;// ../../libs/common/src/admin-console/enums/provider-user-status-type.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var ProviderUserStatusType;
(function (ProviderUserStatusType) {
    ProviderUserStatusType[ProviderUserStatusType["Invited"] = 0] = "Invited";
    ProviderUserStatusType[ProviderUserStatusType["Accepted"] = 1] = "Accepted";
    ProviderUserStatusType[ProviderUserStatusType["Confirmed"] = 2] = "Confirmed";
    ProviderUserStatusType[ProviderUserStatusType["Revoked"] = -1] = "Revoked";
})(ProviderUserStatusType || (ProviderUserStatusType = {}));

;// ../../libs/common/src/admin-console/enums/provider-user-type.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var ProviderUserType;
(function (ProviderUserType) {
    ProviderUserType[ProviderUserType["ProviderAdmin"] = 0] = "ProviderAdmin";
    ProviderUserType[ProviderUserType["ServiceUser"] = 1] = "ServiceUser";
})(ProviderUserType || (ProviderUserType = {}));

;// ../../libs/common/src/admin-console/enums/scim-provider-type.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var ScimProviderType;
(function (ScimProviderType) {
    ScimProviderType[ScimProviderType["Default"] = 0] = "Default";
    ScimProviderType[ScimProviderType["AzureAd"] = 1] = "AzureAd";
    ScimProviderType[ScimProviderType["Okta"] = 2] = "Okta";
    ScimProviderType[ScimProviderType["OneLogin"] = 3] = "OneLogin";
    ScimProviderType[ScimProviderType["JumpCloud"] = 4] = "JumpCloud";
    ScimProviderType[ScimProviderType["GoogleWorkspace"] = 5] = "GoogleWorkspace";
    ScimProviderType[ScimProviderType["Rippling"] = 6] = "Rippling";
})(ScimProviderType || (ScimProviderType = {}));

;// ../../libs/common/src/admin-console/enums/provider-status-type.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var ProviderStatusType;
(function (ProviderStatusType) {
    ProviderStatusType[ProviderStatusType["Pending"] = 0] = "Pending";
    ProviderStatusType[ProviderStatusType["Created"] = 1] = "Created";
    ProviderStatusType[ProviderStatusType["Billable"] = 2] = "Billable";
})(ProviderStatusType || (ProviderStatusType = {}));

;// ../../libs/common/src/admin-console/enums/index.ts











;// ../../libs/common/src/platform/models/domain/domain-base.ts
var domain_base_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};


// https://contributing.bitwarden.com/architecture/clients/data-model#domain
class Domain {
    buildDomainModel(domain, dataObj, map, notEncList = []) {
        for (const prop in map) {
            // eslint-disable-next-line
            if (!map.hasOwnProperty(prop)) {
                continue;
            }
            const objProp = dataObj[map[prop] || prop];
            if (notEncList.indexOf(prop) > -1) {
                domain[prop] = objProp ? objProp : null;
            }
            else {
                domain[prop] = objProp ? new enc_string_EncString(objProp) : null;
            }
        }
    }
    buildDataModel(domain, dataObj, map, notEncStringList = []) {
        for (const prop in map) {
            // eslint-disable-next-line
            if (!map.hasOwnProperty(prop)) {
                continue;
            }
            const objProp = domain[map[prop] || prop];
            if (notEncStringList.indexOf(prop) > -1) {
                dataObj[prop] = objProp != null ? objProp : null;
            }
            else {
                dataObj[prop] = objProp != null ? objProp.encryptedString : null;
            }
        }
    }
    /** @deprecated - Domain encryption must be implemented in the SDK */
    decryptObj(domain_1, viewModel_1, props_1, key_1) {
        return domain_base_awaiter(this, arguments, void 0, function* (domain, viewModel, props, key, objectContext = "No Domain Context") {
            const encryptService = utils_Utils.getContainerService().getEncryptService();
            for (const prop of props) {
                if (domain[prop] == null) {
                    viewModel[prop] = null;
                    continue;
                }
                try {
                    viewModel[prop] = yield encryptService.decryptString(domain[prop], key);
                }
                catch (e) {
                    // In case the SDK maps to a non-Error type, this is defensive
                    const errorMsg = typeof e === "object" && e !== null && "message" in e
                        ? e.message
                        : String(e);
                    // eslint-disable-next-line no-console
                    console.error(`Failed to decrypt property '${String(prop)}' of domain. Context: ${objectContext}. Error: ${errorMsg}`);
                    viewModel[prop] = DECRYPT_ERROR;
                }
            }
            return viewModel;
        });
    }
}

;// ../../libs/common/src/admin-console/models/domain/master-password-policy-options.ts

class MasterPasswordPolicyOptions extends Domain {
    constructor() {
        super(...arguments);
        this.minComplexity = 0;
        this.minLength = 0;
        this.requireUpper = false;
        this.requireLower = false;
        this.requireNumbers = false;
        this.requireSpecial = false;
        /**
         * Flag to indicate if the policy should be enforced on login.
         * If true, and the user's password does not meet the policy requirements,
         * the user will be forced to update their password.
         */
        this.enforceOnLogin = false;
    }
    static fromResponse(policy) {
        if (policy == null) {
            return null;
        }
        const options = new MasterPasswordPolicyOptions();
        options.minComplexity = policy.minComplexity;
        options.minLength = policy.minLength;
        options.requireUpper = policy.requireUpper;
        options.requireLower = policy.requireLower;
        options.requireNumbers = policy.requireNumbers;
        options.requireSpecial = policy.requireSpecial;
        options.enforceOnLogin = policy.enforceOnLogin;
        return options;
    }
}

;// ../../libs/common/src/admin-console/models/data/policy.data.ts
class PolicyData {
    constructor(response) {
        if (response == null) {
            return;
        }
        this.id = response.id;
        this.organizationId = response.organizationId;
        this.type = response.type;
        this.data = response.data;
        this.enabled = response.enabled;
        this.revisionDate = response.revisionDate;
    }
    static fromPolicy(policy) {
        return Object.assign(new PolicyData(), policy);
    }
}

;// ../../libs/common/src/admin-console/models/domain/policy.ts


class Policy extends Domain {
    constructor(obj) {
        super();
        if (obj == null) {
            return;
        }
        this.id = obj.id;
        this.organizationId = obj.organizationId;
        this.type = obj.type;
        this.data = obj.data;
        this.enabled = obj.enabled;
        this.revisionDate = new Date(obj.revisionDate);
    }
    static fromResponse(response) {
        return new Policy(new PolicyData(response));
    }
    static fromListResponse(response) {
        return response.data.map((d) => Policy.fromResponse(d));
    }
}

;// ../../libs/common/src/admin-console/models/domain/reset-password-policy-options.ts

class ResetPasswordPolicyOptions extends Domain {
    constructor() {
        super(...arguments);
        this.autoEnrollEnabled = false;
    }
}

;// ../../libs/common/src/admin-console/services/policy/policy-state.ts

const POLICIES = UserKeyDefinition.record(POLICIES_DISK, "policies", {
    deserializer: (policyData) => policyData,
    clearOn: ["logout"],
});

;// ../../libs/common/src/admin-console/services/policy/default-policy.service.ts
var default_policy_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};







function policyRecordToArray(policiesMap) {
    return Object.values(policiesMap || {}).map((f) => new Policy(f));
}
const getFirstPolicy = (0,external_rxjs_namespaceObject.map)((policies) => {
    var _a;
    return (_a = policies.at(0)) !== null && _a !== void 0 ? _a : undefined;
});
class DefaultPolicyService {
    constructor(stateProvider, organizationService, accountService) {
        this.stateProvider = stateProvider;
        this.organizationService = organizationService;
        this.accountService = accountService;
    }
    policyState(userId) {
        return this.stateProvider.getUser(userId, POLICIES);
    }
    policyData$(userId) {
        return this.policyState(userId).state$.pipe((0,external_rxjs_namespaceObject.map)((policyData) => policyData !== null && policyData !== void 0 ? policyData : {}));
    }
    policies$(userId) {
        return this.policyData$(userId).pipe((0,external_rxjs_namespaceObject.map)((policyData) => policyRecordToArray(policyData)));
    }
    policiesByType$(policyType, userId) {
        if (!userId) {
            throw new Error("No userId provided");
        }
        const allPolicies$ = this.policies$(userId);
        const organizations$ = this.organizationService.organizations$(userId);
        return (0,external_rxjs_namespaceObject.combineLatest)([allPolicies$, organizations$]).pipe((0,external_rxjs_namespaceObject.map)(([policies, organizations]) => this.enforcedPolicyFilter(policies, organizations)), (0,external_rxjs_namespaceObject.map)((policies) => policies.filter((p) => p.type === policyType)));
    }
    policyAppliesToUser$(policyType, userId) {
        return this.policiesByType$(policyType, userId).pipe(getFirstPolicy, (0,external_rxjs_namespaceObject.map)((policy) => !!policy));
    }
    enforcedPolicyFilter(policies, organizations) {
        const orgDict = Object.fromEntries(organizations.map((o) => [o.id, o]));
        return policies.filter((policy) => {
            const organization = orgDict[policy.organizationId];
            // This shouldn't happen, i.e. the user should only have policies for orgs they are a member of
            // But if it does, err on the side of enforcing the policy
            if (!organization) {
                return true;
            }
            return (policy.enabled &&
                organization.status >= organization_user_status_type_enum_OrganizationUserStatusType.Accepted &&
                organization.usePolicies &&
                !this.isExemptFromPolicy(policy.type, organization, policies));
        });
    }
    masterPasswordPolicyOptions$(userId, policies) {
        const policies$ = policies
            ? (0,external_rxjs_namespaceObject.of)(policies)
            : this.policiesByType$(policy_type_enum_PolicyType.MasterPassword, userId);
        return policies$.pipe((0,external_rxjs_namespaceObject.map)((obsPolicies) => {
            var _a;
            // TODO ([PM-23777]): replace with this.combinePoliciesIntoMasterPasswordPolicyOptions(obsPolicies))
            let enforcedOptions = undefined;
            const filteredPolicies = (_a = obsPolicies.filter((p) => p.type === policy_type_enum_PolicyType.MasterPassword)) !== null && _a !== void 0 ? _a : [];
            if (filteredPolicies.length === 0) {
                return;
            }
            filteredPolicies.forEach((currentPolicy) => {
                if (!currentPolicy.enabled || !currentPolicy.data) {
                    return;
                }
                if (!enforcedOptions) {
                    enforcedOptions = new MasterPasswordPolicyOptions();
                }
                if (currentPolicy.data.minComplexity != null &&
                    currentPolicy.data.minComplexity > enforcedOptions.minComplexity) {
                    enforcedOptions.minComplexity = currentPolicy.data.minComplexity;
                }
                if (currentPolicy.data.minLength != null &&
                    currentPolicy.data.minLength > enforcedOptions.minLength) {
                    enforcedOptions.minLength = currentPolicy.data.minLength;
                }
                if (currentPolicy.data.requireUpper) {
                    enforcedOptions.requireUpper = true;
                }
                if (currentPolicy.data.requireLower) {
                    enforcedOptions.requireLower = true;
                }
                if (currentPolicy.data.requireNumbers) {
                    enforcedOptions.requireNumbers = true;
                }
                if (currentPolicy.data.requireSpecial) {
                    enforcedOptions.requireSpecial = true;
                }
                if (currentPolicy.data.enforceOnLogin) {
                    enforcedOptions.enforceOnLogin = true;
                }
            });
            return enforcedOptions;
        }));
    }
    combinePoliciesIntoMasterPasswordPolicyOptions(policies) {
        var _a;
        let enforcedOptions = undefined;
        const filteredPolicies = (_a = policies.filter((p) => p.type === policy_type_enum_PolicyType.MasterPassword)) !== null && _a !== void 0 ? _a : [];
        if (filteredPolicies.length === 0) {
            return;
        }
        filteredPolicies.forEach((currentPolicy) => {
            if (!currentPolicy.enabled || !currentPolicy.data) {
                return undefined;
            }
            if (!enforcedOptions) {
                enforcedOptions = new MasterPasswordPolicyOptions();
            }
            this.mergeMasterPasswordPolicyOptions(enforcedOptions, currentPolicy.data);
        });
        return enforcedOptions;
    }
    combineMasterPasswordPolicyOptions(...policies) {
        let combinedOptions = undefined;
        policies.forEach((currentOptions) => {
            if (!combinedOptions) {
                combinedOptions = new MasterPasswordPolicyOptions();
            }
            this.mergeMasterPasswordPolicyOptions(combinedOptions, currentOptions);
        });
        return combinedOptions;
    }
    evaluateMasterPassword(passwordStrength, newPassword, enforcedPolicyOptions) {
        if (!enforcedPolicyOptions) {
            return true;
        }
        if (enforcedPolicyOptions.minComplexity > 0 &&
            enforcedPolicyOptions.minComplexity > passwordStrength) {
            return false;
        }
        if (enforcedPolicyOptions.minLength > 0 &&
            enforcedPolicyOptions.minLength > newPassword.length) {
            return false;
        }
        if (enforcedPolicyOptions.requireUpper && newPassword.toLocaleLowerCase() === newPassword) {
            return false;
        }
        if (enforcedPolicyOptions.requireLower && newPassword.toLocaleUpperCase() === newPassword) {
            return false;
        }
        if (enforcedPolicyOptions.requireNumbers && !/[0-9]/.test(newPassword)) {
            return false;
        }
        // eslint-disable-next-line
        if (enforcedPolicyOptions.requireSpecial && !/[!@#$%\^&*]/g.test(newPassword)) {
            return false;
        }
        return true;
    }
    getResetPasswordPolicyOptions(policies, orgId) {
        var _a, _b, _c;
        const resetPasswordPolicyOptions = new ResetPasswordPolicyOptions();
        if (!policies || !orgId) {
            return [resetPasswordPolicyOptions, false];
        }
        const policy = policies.find((p) => p.organizationId === orgId && p.type === policy_type_enum_PolicyType.ResetPassword && p.enabled);
        resetPasswordPolicyOptions.autoEnrollEnabled = (_b = (_a = policy === null || policy === void 0 ? void 0 : policy.data) === null || _a === void 0 ? void 0 : _a.autoEnrollEnabled) !== null && _b !== void 0 ? _b : false;
        return [resetPasswordPolicyOptions, (_c = policy === null || policy === void 0 ? void 0 : policy.enabled) !== null && _c !== void 0 ? _c : false];
    }
    upsert(policy, userId) {
        return default_policy_service_awaiter(this, void 0, void 0, function* () {
            yield this.policyState(userId).update((policies) => {
                policies !== null && policies !== void 0 ? policies : (policies = {});
                policies[policy.id] = policy;
                return policies;
            });
        });
    }
    replace(policies, userId) {
        return default_policy_service_awaiter(this, void 0, void 0, function* () {
            yield this.stateProvider.setUserState(POLICIES, policies, userId);
        });
    }
    /**
     * Determines whether an orgUser is exempt from a specific policy because of their role
     * Generally orgUsers who can manage policies are exempt from them, but some policies are stricter
     */
    isExemptFromPolicy(policyType, organization, allPolicies) {
        switch (policyType) {
            case policy_type_enum_PolicyType.MaximumVaultTimeout:
                // Max Vault Timeout applies to everyone except owners
                return organization.isOwner;
            // the following policies apply to everyone
            case policy_type_enum_PolicyType.PasswordGenerator:
                // password generation policy
                return false;
            case policy_type_enum_PolicyType.FreeFamiliesSponsorshipPolicy:
                // free Bitwarden families policy
                return false;
            case policy_type_enum_PolicyType.RestrictedItemTypes:
                // restricted item types policy
                return false;
            case policy_type_enum_PolicyType.RemoveUnlockWithPin:
                // Remove Unlock with PIN policy
                return false;
            case policy_type_enum_PolicyType.AutoConfirm:
                return false;
            case policy_type_enum_PolicyType.MasterPassword:
                // MasterPassword policy applies to everyone, including admins and owners
                return false;
            case policy_type_enum_PolicyType.OrganizationDataOwnership:
                // organization data ownership policy applies to everyone except admins and owners
                return organization.isAdmin;
            case policy_type_enum_PolicyType.SingleOrg:
                // Check if AutoConfirm policy is enabled for this organization
                return allPolicies.find((p) => p.organizationId === organization.id && p.type === policy_type_enum_PolicyType.AutoConfirm && p.enabled)
                    ? false
                    : organization.canManagePolicies;
            default:
                return organization.canManagePolicies;
        }
    }
    mergeMasterPasswordPolicyOptions(target, source) {
        var _a, _b;
        if (!target) {
            target = new MasterPasswordPolicyOptions();
        }
        // For complexity and minLength, take the highest value.
        // For boolean settings, enable it if either policy has it enabled (OR).
        if (source) {
            target.minComplexity = Math.max(target.minComplexity, (_a = source.minComplexity) !== null && _a !== void 0 ? _a : target.minComplexity);
            target.minLength = Math.max(target.minLength, (_b = source.minLength) !== null && _b !== void 0 ? _b : target.minLength);
            target.requireUpper = Boolean(target.requireUpper || source.requireUpper);
            target.requireLower = Boolean(target.requireLower || source.requireLower);
            target.requireNumbers = Boolean(target.requireNumbers || source.requireNumbers);
            target.requireSpecial = Boolean(target.requireSpecial || source.requireSpecial);
            target.enforceOnLogin = Boolean(target.enforceOnLogin || source.enforceOnLogin);
        }
    }
    syncPolicy(policyData) {
        return default_policy_service_awaiter(this, void 0, void 0, function* () {
            yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId, (0,external_rxjs_namespaceObject.switchMap)((userId) => this.upsert(policyData, userId))));
        });
    }
}

;// ../../libs/common/src/key-management/vault-timeout/enums/vault-timeout-action.enum.ts
const VaultTimeoutAction = {
    Lock: "lock",
    LogOut: "logOut",
};

;// ../../libs/common/src/key-management/vault-timeout/types/vault-timeout.type.ts
// Note: the below comments are just for documenting what they used to be.
const VaultTimeoutStringType = {
    Never: "never", // null
    OnRestart: "onRestart", // -1
    OnLocked: "onLocked", // -2
    OnSleep: "onSleep", // -3
    OnIdle: "onIdle", // -4
    Custom: "custom", // -100
};
const VaultTimeoutNumberType = {
    Immediately: 0,
    OnMinute: 1,
    EightHours: 480,
};
function isVaultTimeoutTypeNumeric(timeout) {
    return typeof timeout === "number";
}

;// ../../libs/common/src/key-management/vault-timeout/services/vault-timeout-settings.state.ts

/**
 * Settings use disk storage and local storage on web so settings can persist after logout
 * in order for us to know if the user's chose to never lock their vault or not.
 * When the user has never lock selected, we have to set the user key in memory
 * from the user auto unlock key stored on disk on client bootstrap.
 */
const vault_timeout_settings_state_VAULT_TIMEOUT_ACTION = new UserKeyDefinition(VAULT_TIMEOUT_SETTINGS_DISK_LOCAL, "vaultTimeoutAction", {
    deserializer: (vaultTimeoutAction) => vaultTimeoutAction,
    clearOn: [], // persisted on logout
});
const vault_timeout_settings_state_VAULT_TIMEOUT = new UserKeyDefinition(VAULT_TIMEOUT_SETTINGS_DISK_LOCAL, "vaultTimeout", {
    deserializer: (vaultTimeout) => vaultTimeout,
    clearOn: [], // persisted on logout
});
const VAULT_TIMEOUT_SUPPRESSED_UNTIL = new UserKeyDefinition(VAULT_TIMEOUT_SETTINGS_MEMORY, "vaultTimeoutSuppressedUntil", {
    deserializer: (value) => value,
    clearOn: ["logout"],
});

;// ../../libs/common/src/key-management/vault-timeout/services/vault-timeout-settings.service.ts
var vault_timeout_settings_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore







class VaultTimeoutSettingsService {
    constructor(accountService, pinStateService, userDecryptionOptionsService, keyService, tokenService, policyService, biometricStateService, stateProvider, logService, defaultVaultTimeout, sessionTimeoutTypeService) {
        this.accountService = accountService;
        this.pinStateService = pinStateService;
        this.userDecryptionOptionsService = userDecryptionOptionsService;
        this.keyService = keyService;
        this.tokenService = tokenService;
        this.policyService = policyService;
        this.biometricStateService = biometricStateService;
        this.stateProvider = stateProvider;
        this.logService = logService;
        this.defaultVaultTimeout = defaultVaultTimeout;
        this.sessionTimeoutTypeService = sessionTimeoutTypeService;
    }
    setVaultTimeoutOptions(userId, timeout, action) {
        return vault_timeout_settings_service_awaiter(this, void 0, void 0, function* () {
            if (!userId) {
                throw new Error("User id required. Cannot set vault timeout settings.");
            }
            if (timeout == null) {
                throw new Error("Vault Timeout cannot be null.");
            }
            if (action == null) {
                throw new Error("Vault Timeout Action cannot be null.");
            }
            yield this.setVaultTimeout(userId, timeout);
            yield this.setVaultTimeoutAction(userId, action);
            yield this.migrateTokenStorage(userId, action, timeout);
            yield this.keyService.refreshAdditionalKeys(userId);
        });
    }
    availableVaultTimeoutActions$(userId) {
        const userId$ = userId != null
            ? (0,external_rxjs_namespaceObject.of)(userId)
            : // TODO remove with https://bitwarden.atlassian.net/browse/PM-10647
                account_service_getUserId(this.accountService.activeAccount$);
        return userId$.pipe((0,external_rxjs_namespaceObject.switchMap)((userId) => (0,external_rxjs_namespaceObject.combineLatest)([
            this.userDecryptionOptionsService.hasMasterPasswordById$(userId),
            this.biometricStateService.biometricUnlockEnabled$(userId),
            this.pinStateService.pinSet$(userId),
        ])), (0,external_rxjs_namespaceObject.map)(([haveMasterPassword, biometricUnlockEnabled, isPinSet]) => {
            const canLock = haveMasterPassword || biometricUnlockEnabled || isPinSet;
            if (canLock) {
                return [VaultTimeoutAction.LogOut, VaultTimeoutAction.Lock];
            }
            return [VaultTimeoutAction.LogOut];
        }));
    }
    canLock(userId) {
        return vault_timeout_settings_service_awaiter(this, void 0, void 0, function* () {
            const availableVaultTimeoutActions = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.availableVaultTimeoutActions$(userId));
            return (availableVaultTimeoutActions === null || availableVaultTimeoutActions === void 0 ? void 0 : availableVaultTimeoutActions.includes(VaultTimeoutAction.Lock)) || false;
        });
    }
    isBiometricLockSet(userId) {
        return vault_timeout_settings_service_awaiter(this, void 0, void 0, function* () {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.biometricStateService.biometricUnlockEnabled$(userId));
        });
    }
    setVaultTimeout(userId, timeout) {
        return vault_timeout_settings_service_awaiter(this, void 0, void 0, function* () {
            if (!userId) {
                throw new Error("User id required. Cannot set vault timeout.");
            }
            if (timeout == null) {
                throw new Error("Vault Timeout cannot be null.");
            }
            yield this.stateProvider.setUserState(vault_timeout_settings_state_VAULT_TIMEOUT, timeout, userId);
        });
    }
    getVaultTimeoutByUserId$(userId) {
        if (!userId) {
            throw new Error("User id required. Cannot get vault timeout.");
        }
        return (0,external_rxjs_namespaceObject.combineLatest)([
            this.stateProvider.getUserState$(vault_timeout_settings_state_VAULT_TIMEOUT, userId),
            this.getMaxSessionTimeoutPolicyDataByUserId$(userId),
        ]).pipe((0,external_rxjs_namespaceObject.switchMap)(([currentVaultTimeout, maxSessionTimeoutPolicyData]) => {
            this.logService.debug("[VaultTimeoutSettingsService] Current vault timeout is %o for user id %s, max session policy %o", currentVaultTimeout, userId, maxSessionTimeoutPolicyData);
            return (0,external_rxjs_namespaceObject.from)(this.determineVaultTimeout(currentVaultTimeout, maxSessionTimeoutPolicyData)).pipe((0,external_rxjs_namespaceObject.concatMap)((vaultTimeout) => vault_timeout_settings_service_awaiter(this, void 0, void 0, function* () {
                this.logService.debug("[VaultTimeoutSettingsService] Determined vault timeout is %o for user id %s", vaultTimeout, userId);
                // As a side effect, set the new value determined by determineVaultTimeout into state if it's different from the current
                if (vaultTimeout !== currentVaultTimeout) {
                    yield this.stateProvider.setUserState(vault_timeout_settings_state_VAULT_TIMEOUT, vaultTimeout, userId);
                }
                return vaultTimeout;
            })), (0,external_rxjs_namespaceObject.catchError)((error) => {
                // Protect outer observable from canceling on error by catching and returning EMPTY
                this.logService.error(`Error getting vault timeout: ${error}`);
                return external_rxjs_namespaceObject.EMPTY;
            }));
        }), (0,external_rxjs_namespaceObject.distinctUntilChanged)(), // Avoid having the set side effect trigger a new emission of the same action
        (0,external_rxjs_namespaceObject.shareReplay)({ refCount: true, bufferSize: 1 }));
    }
    determineVaultTimeout(currentVaultTimeout, maxSessionTimeoutPolicyData) {
        return vault_timeout_settings_service_awaiter(this, void 0, void 0, function* () {
            const determinedTimeout = yield this.determineVaultTimeoutInternal(currentVaultTimeout, maxSessionTimeoutPolicyData);
            // Ensures the timeout is available on this client
            return yield this.sessionTimeoutTypeService.getOrPromoteToAvailable(determinedTimeout);
        });
    }
    determineVaultTimeoutInternal(currentVaultTimeout, maxSessionTimeoutPolicyData) {
        return vault_timeout_settings_service_awaiter(this, void 0, void 0, function* () {
            // if current vault timeout is null, apply the client specific default
            currentVaultTimeout = currentVaultTimeout !== null && currentVaultTimeout !== void 0 ? currentVaultTimeout : this.defaultVaultTimeout;
            // If no policy applies, return the current vault timeout
            if (maxSessionTimeoutPolicyData == null) {
                return currentVaultTimeout;
            }
            switch (maxSessionTimeoutPolicyData.type) {
                case "immediately":
                    return VaultTimeoutNumberType.Immediately;
                case "custom":
                case null:
                case undefined:
                    if (currentVaultTimeout === VaultTimeoutNumberType.Immediately) {
                        return currentVaultTimeout;
                    }
                    if (isVaultTimeoutTypeNumeric(currentVaultTimeout)) {
                        return Math.min(currentVaultTimeout, maxSessionTimeoutPolicyData.minutes);
                    }
                    return maxSessionTimeoutPolicyData.minutes;
                case "onSystemLock":
                    if (currentVaultTimeout === VaultTimeoutStringType.Never ||
                        currentVaultTimeout === VaultTimeoutStringType.OnRestart ||
                        currentVaultTimeout === VaultTimeoutStringType.OnLocked ||
                        currentVaultTimeout === VaultTimeoutStringType.OnIdle ||
                        currentVaultTimeout === VaultTimeoutStringType.OnSleep) {
                        return VaultTimeoutStringType.OnLocked;
                    }
                    break;
                case "onAppRestart":
                    if (currentVaultTimeout === VaultTimeoutStringType.Never ||
                        currentVaultTimeout === VaultTimeoutStringType.OnLocked ||
                        currentVaultTimeout === VaultTimeoutStringType.OnIdle ||
                        currentVaultTimeout === VaultTimeoutStringType.OnSleep) {
                        return VaultTimeoutStringType.OnRestart;
                    }
                    break;
                case "never":
                    // Policy doesn't override user preference for "never"
                    break;
            }
            return currentVaultTimeout;
        });
    }
    /**
     * Re-stores tokens in the correct location (memory vs disk) for the given action and timeout.
     */
    migrateTokenStorage(userId, action, timeout) {
        return vault_timeout_settings_service_awaiter(this, void 0, void 0, function* () {
            // Read tokens before any clearing so they can be re-stored in the new location
            const accessToken = yield this.tokenService.getAccessToken(userId);
            const refreshToken = yield this.tokenService.getRefreshToken(userId);
            const clientId = yield this.tokenService.getClientId(userId);
            const clientSecret = yield this.tokenService.getClientSecret(userId);
            if (!accessToken) {
                return;
            }
            yield this.tokenService.setTokens(accessToken, action, timeout, refreshToken, [
                clientId,
                clientSecret,
            ]);
        });
    }
    setVaultTimeoutAction(userId, action) {
        return vault_timeout_settings_service_awaiter(this, void 0, void 0, function* () {
            if (!userId) {
                throw new Error("User id required. Cannot set vault timeout action.");
            }
            if (!action) {
                throw new Error("Vault Timeout Action cannot be null");
            }
            yield this.stateProvider.setUserState(vault_timeout_settings_state_VAULT_TIMEOUT_ACTION, action, userId);
        });
    }
    getVaultTimeoutActionByUserId$(userId) {
        if (!userId) {
            throw new Error("User id required. Cannot get vault timeout action.");
        }
        return (0,external_rxjs_namespaceObject.combineLatest)([
            this.stateProvider.getUserState$(vault_timeout_settings_state_VAULT_TIMEOUT_ACTION, userId),
            this.getMaxSessionTimeoutPolicyDataByUserId$(userId),
            this.availableVaultTimeoutActions$(userId),
            this.getVaultTimeoutByUserId$(userId),
        ]).pipe((0,external_rxjs_namespaceObject.concatMap)((_a) => vault_timeout_settings_service_awaiter(this, [_a], void 0, function* ([currentVaultTimeoutAction, maxSessionTimeoutPolicyData, availableVaultTimeoutActions, vaultTimeout,]) {
            const vaultTimeoutAction = this.determineVaultTimeoutAction(availableVaultTimeoutActions, currentVaultTimeoutAction, maxSessionTimeoutPolicyData);
            // As a side effect, persist the determined action back to state when needed.
            const oneActionAvailable = availableVaultTimeoutActions.length === 1;
            if (oneActionAvailable) {
                const availableAction = availableVaultTimeoutActions[0];
                // Always reset to null when only one action is available — even if the stored action
                // matches. Ensures the default (Lock) is used when an unlock method (e.g. PIN) is
                // re-enabled later.
                if (currentVaultTimeoutAction !== null) {
                    yield this.stateProvider.setUserState(vault_timeout_settings_state_VAULT_TIMEOUT_ACTION, null, userId);
                    // Only migrate tokens if the actual action changes (e.g. Lock → LogOut).
                    // No migration needed when stored action already matches the only available one.
                    if (currentVaultTimeoutAction !== availableAction) {
                        yield this.migrateTokenStorage(userId, availableAction, vaultTimeout);
                    }
                }
            }
            else if (vaultTimeoutAction !== currentVaultTimeoutAction) {
                yield this.stateProvider.setUserState(vault_timeout_settings_state_VAULT_TIMEOUT_ACTION, vaultTimeoutAction, userId);
                // Migrate tokens when effective action changes from LogOut (memory) to Lock (disk).
                // currentVaultTimeoutAction is null when forced LogOut was reset to null by the
                // side effect (no unlock methods) or the state migrator.
                if (currentVaultTimeoutAction === null &&
                    vaultTimeoutAction === VaultTimeoutAction.Lock) {
                    yield this.migrateTokenStorage(userId, vaultTimeoutAction, vaultTimeout);
                }
            }
            return vaultTimeoutAction;
        })), (0,external_rxjs_namespaceObject.catchError)((error) => {
            // Protect outer observable from canceling on error by catching and returning EMPTY
            this.logService.error(`Error getting vault timeout: ${error}`);
            return external_rxjs_namespaceObject.EMPTY;
        }), (0,external_rxjs_namespaceObject.distinctUntilChanged)(), // Avoid having the set side effect trigger a new emission of the same action
        (0,external_rxjs_namespaceObject.shareReplay)({ refCount: true, bufferSize: 1 }));
    }
    determineVaultTimeoutAction(availableVaultTimeoutActions, currentVaultTimeoutAction, maxSessionTimeoutPolicyData) {
        if (availableVaultTimeoutActions.length === 1) {
            return availableVaultTimeoutActions[0];
        }
        if ((maxSessionTimeoutPolicyData === null || maxSessionTimeoutPolicyData === void 0 ? void 0 : maxSessionTimeoutPolicyData.action) &&
            availableVaultTimeoutActions.includes(maxSessionTimeoutPolicyData.action)) {
            // return policy defined session timeout action
            return maxSessionTimeoutPolicyData.action;
        }
        // No policy applies from here on
        // If the current vault timeout is null and lock is an option, set it as the default
        if (currentVaultTimeoutAction == null &&
            availableVaultTimeoutActions.includes(VaultTimeoutAction.Lock)) {
            return VaultTimeoutAction.Lock;
        }
        return currentVaultTimeoutAction;
    }
    getMaxSessionTimeoutPolicyDataByUserId$(userId) {
        if (!userId) {
            throw new Error("User id required. Cannot get max session timeout policy.");
        }
        return this.policyService.policiesByType$(policy_type_enum_PolicyType.MaximumVaultTimeout, userId).pipe(getFirstPolicy, (0,external_rxjs_namespaceObject.map)((policy) => { var _a; return ((_a = policy === null || policy === void 0 ? void 0 : policy.data) !== null && _a !== void 0 ? _a : null); }));
    }
    vaultTimeoutSuppressedUntil$(userId) {
        if (!userId) {
            throw new Error("User id required. Cannot get vault timeout suppressed until.");
        }
        return this.stateProvider.getUserState$(VAULT_TIMEOUT_SUPPRESSED_UNTIL, userId);
    }
    isVaultTimeoutSuppressed$(userId) {
        return this.vaultTimeoutSuppressedUntil$(userId).pipe((0,external_rxjs_namespaceObject.map)((until) => until != null && Date.now() < until));
    }
    isVaultTimeoutSuppressed(userId) {
        return vault_timeout_settings_service_awaiter(this, void 0, void 0, function* () {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.isVaultTimeoutSuppressed$(userId));
        });
    }
    suppressVaultTimeout(until, userId) {
        return vault_timeout_settings_service_awaiter(this, void 0, void 0, function* () {
            if (!userId) {
                throw new Error("User id required. Cannot suppress vault timeout.");
            }
            yield this.stateProvider.getUser(userId, VAULT_TIMEOUT_SUPPRESSED_UNTIL).update(() => until);
        });
    }
    clearVaultTimeoutSuppression(userId) {
        return vault_timeout_settings_service_awaiter(this, void 0, void 0, function* () {
            if (!userId) {
                throw new Error("User id required. Cannot clear vault timeout suppression.");
            }
            yield this.stateProvider.getUser(userId, VAULT_TIMEOUT_SUPPRESSED_UNTIL).update(() => null);
        });
    }
}

;// ../../libs/scheduling/src/scheduled-task-name.enum.ts
const ScheduledTaskNames = {
    generatePasswordClearClipboardTimeout: "generatePasswordClearClipboardTimeout",
    systemClearClipboardTimeout: "systemClearClipboardTimeout",
    loginStrategySessionTimeout: "loginStrategySessionTimeout",
    notificationsReconnectTimeout: "notificationsReconnectTimeout",
    fido2ClientAbortTimeout: "fido2ClientAbortTimeout",
    scheduleNextSyncInterval: "scheduleNextSyncInterval",
    eventUploadsInterval: "eventUploadsInterval",
    vaultTimeoutCheckInterval: "vaultTimeoutCheckInterval",
    clearPopupViewCache: "clearPopupViewCache",
    targetingRulesUpdate: "targetingRulesUpdate",
    phishingDomainUpdate: "phishingDomainUpdate",
};

;// ../../libs/scheduling/src/task-scheduler.service.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

/**
 * Creates a RXJS scheduler based on a {@link TaskSchedulerService}.
 *
 * @description This API defers to `TaskSchedulerService` to schedule a task to be ran
 * in the future but the task that is ran is NOT the remainder of your RXJS pipeline. The
 * task you want ran must instead be registered in a location reachable on a service worker
 * startup (on browser). An example of an acceptible location is the constructor of a service
 * you know is created in `MainBackground`. Uses of this API in other clients _can_ have the
 * `registerTaskHandler` call in more places, but in order to have it work across clients
 * it is recommended to register it according to the rules of browser.
 *
 * @link https://rxjs.dev/guide/scheduler#using-schedulers
 *
 * @example
 * ```ts
 * class MyService {
 *   constructor(messageListener: MessageListener, taskScheduler: TaskSchedulerService) {
 *    // VERY IMPORTANT!
 *    this.taskSchedulerService.registerTaskHandler(SchedulerTaskNames.myTaskName, async () => {
 *      await this.runEvent();
 *    });
 *
 *     messageListener.messages$(MY_MESSAGE).pipe(
 *        debounceTime(
 *          10 * 1000,
 *          toScheduler(taskScheduler, ShedulerTaskNames.myTaskName),
 *        ),
 *        switchMap(() => this.runEvent()),
 *     )
 *   }
 * }
 * ```
 *
 * @param taskScheduler The task scheduler service to use to shedule RXJS work.
 * @param taskName The name of the task that the handler should be registered and scheduled based on.
 * @returns A SchedulerLike object that can be passed in to RXJS operators like `delay` and `timeout`.
 */
function toScheduler(taskScheduler, taskName) {
    return new TaskSchedulerSheduler(taskScheduler, taskName);
}
class TaskSchedulerSheduler {
    constructor(taskSchedulerService, taskName) {
        this.taskSchedulerService = taskSchedulerService;
        this.taskName = taskName;
    }
    schedule(work, delay, state) {
        return this.taskSchedulerService.setTimeout(this.taskName, delay !== null && delay !== void 0 ? delay : 0);
    }
    now() {
        return asyncScheduler.now();
    }
}
class TaskSchedulerService {
}

;// ../../libs/scheduling/src/default-task-scheduler.service.ts
var default_task_scheduler_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};


class DefaultTaskSchedulerService extends TaskSchedulerService {
    constructor(logService) {
        super();
        this.logService = logService;
        this.taskHandlers = new Map();
    }
    /**
     * Sets a timeout and returns the timeout id.
     *
     * @param taskName - The name of the task. Unused in the base implementation.
     * @param delayInMs - The delay in milliseconds.
     */
    setTimeout(taskName, delayInMs) {
        this.validateRegisteredTask(taskName);
        const timeoutHandle = globalThis.setTimeout(() => this.triggerTask(taskName), delayInMs);
        return new external_rxjs_namespaceObject.Subscription(() => globalThis.clearTimeout(timeoutHandle));
    }
    /**
     * Sets an interval and returns the interval id.
     *
     * @param taskName - The name of the task. Unused in the base implementation.
     * @param intervalInMs - The interval in milliseconds.
     * @param _initialDelayInMs - The initial delay in milliseconds. Unused in the base implementation.
     */
    setInterval(taskName, intervalInMs, _initialDelayInMs) {
        this.validateRegisteredTask(taskName);
        const intervalHandle = globalThis.setInterval(() => this.triggerTask(taskName), intervalInMs);
        return new external_rxjs_namespaceObject.Subscription(() => globalThis.clearInterval(intervalHandle));
    }
    /**
     * Registers a task handler.
     *
     * @param taskName - The name of the task.
     * @param handler - The task handler.
     */
    registerTaskHandler(taskName, handler) {
        const existingHandler = this.taskHandlers.get(taskName);
        if (existingHandler) {
            this.logService.warning(`Task handler for ${taskName} already exists. Overwriting.`);
            this.unregisterTaskHandler(taskName);
        }
        this.taskHandlers.set(taskName, handler);
    }
    /**
     * Unregisters a task handler.
     *
     * @param taskName - The name of the task.
     */
    unregisterTaskHandler(taskName) {
        this.taskHandlers.delete(taskName);
    }
    /**
     * Triggers a task.
     *
     * @param taskName - The name of the task.
     * @param _periodInMinutes - The period in minutes. Unused in the base implementation.
     */
    triggerTask(taskName, _periodInMinutes) {
        return default_task_scheduler_service_awaiter(this, void 0, void 0, function* () {
            const handler = this.taskHandlers.get(taskName);
            if (handler) {
                handler();
            }
        });
    }
    /**
     * Validates that a task handler is registered.
     *
     * @param taskName - The name of the task.
     */
    validateRegisteredTask(taskName) {
        if (!this.taskHandlers.has(taskName)) {
            throw new Error(`Task handler for ${taskName} not registered. Unable to schedule task.`);
        }
    }
}

;// ../../libs/scheduling/src/index.ts




;// ../../libs/common/src/platform/scheduling/index.ts


;// ../../libs/common/src/key-management/vault-timeout/services/vault-timeout.service.ts
var vault_timeout_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore




class VaultTimeoutService {
    constructor(accountService, platformUtilsService, authService, vaultTimeoutSettingsService, taskSchedulerService, logService, lockService, logoutService) {
        this.accountService = accountService;
        this.platformUtilsService = platformUtilsService;
        this.authService = authService;
        this.vaultTimeoutSettingsService = vaultTimeoutSettingsService;
        this.taskSchedulerService = taskSchedulerService;
        this.logService = logService;
        this.lockService = lockService;
        this.logoutService = logoutService;
        this.inited = false;
        this.taskSchedulerService.registerTaskHandler(ScheduledTaskNames.vaultTimeoutCheckInterval, () => this.checkVaultTimeout());
    }
    init(checkOnInterval) {
        return vault_timeout_service_awaiter(this, void 0, void 0, function* () {
            if (this.inited) {
                return;
            }
            this.inited = true;
            if (checkOnInterval) {
                this.startCheck();
            }
        });
    }
    startCheck() {
        this.checkVaultTimeout().catch((error) => this.logService.error(error));
        this.taskSchedulerService.setInterval(ScheduledTaskNames.vaultTimeoutCheckInterval, 10 * 1000);
    }
    checkVaultTimeout() {
        return vault_timeout_service_awaiter(this, void 0, void 0, function* () {
            // Get whether or not any view is focused a single time so it can be compared for each user
            const isViewFocused = yield this.platformUtilsService.isAnyViewFocused();
            yield (0,external_rxjs_namespaceObject.firstValueFrom)((0,external_rxjs_namespaceObject.combineLatest)([
                this.accountService.activeAccount$,
                this.accountService.accountActivity$,
            ]).pipe((0,external_rxjs_namespaceObject.concatMap)((_a) => vault_timeout_service_awaiter(this, [_a], void 0, function* ([activeAccount, accountActivity]) {
                const activeUserId = activeAccount === null || activeAccount === void 0 ? void 0 : activeAccount.id;
                for (const userIdString in accountActivity) {
                    const userId = userIdString;
                    if (userId != null &&
                        (yield this.shouldLock(userId, accountActivity[userId], activeUserId, isViewFocused))) {
                        yield this.executeTimeoutAction(userId);
                    }
                }
            }))));
        });
    }
    shouldLock(userId, lastActive, activeUserId, isViewFocused) {
        return vault_timeout_service_awaiter(this, void 0, void 0, function* () {
            if (isViewFocused && userId === activeUserId) {
                // We know a view is focused and this is the currently active user
                // which means they are likely looking at their vault
                // and they should not lock.
                return false;
            }
            // Check if vault timeout is suppressed by shared unlock
            if (yield this.vaultTimeoutSettingsService.isVaultTimeoutSuppressed(userId)) {
                return false;
            }
            const authStatus = yield this.authService.getAuthStatus(userId);
            if (authStatus === authentication_status_AuthenticationStatus.Locked ||
                authStatus === authentication_status_AuthenticationStatus.LoggedOut) {
                return false;
            }
            const vaultTimeout = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.vaultTimeoutSettingsService.getVaultTimeoutByUserId$(userId));
            if (typeof vaultTimeout === "string") {
                return false;
            }
            if (lastActive == null) {
                return false;
            }
            const vaultTimeoutSeconds = vaultTimeout * 60;
            const diffSeconds = (new Date().getTime() - lastActive.getTime()) / 1000;
            return diffSeconds >= vaultTimeoutSeconds;
        });
    }
    executeTimeoutAction(userId) {
        return vault_timeout_service_awaiter(this, void 0, void 0, function* () {
            const timeoutAction = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.vaultTimeoutSettingsService.getVaultTimeoutActionByUserId$(userId));
            timeoutAction === VaultTimeoutAction.LogOut
                ? yield this.logoutService.logout(userId, "vaultTimeout")
                : yield this.lockService.lock(userId);
        });
    }
}

;// ../../libs/common/src/key-management/vault-timeout/index.ts






// Only used by desktop's electron-key.service.spec.ts test


;// ../../libs/common/src/platform/misc/convert-values.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

/**
 * Converts a record of keys and values into a record preserving the original key and converting each value into an {@link ObservableInput}.
 * @param project A function to project a given key and value pair into an {@link ObservableInput}
 */
function convertValues(project) {
    return (0,external_rxjs_namespaceObject.map)((inputRecord) => {
        if (inputRecord == null) {
            return null;
        }
        // Can't use TKey in here, have to use `PropertyKey`
        const result = {};
        for (const [key, value] of Object.entries(inputRecord)) {
            result[key] = project(key, value);
        }
        return result;
    });
}

;// ../../libs/common/src/platform/misc/wordlist.ts
// EFF's Long Wordlist from https://www.eff.org/dice
const EFFLongWordList = [
    "abacus",
    "abdomen",
    "abdominal",
    "abide",
    "abiding",
    "ability",
    "ablaze",
    "able",
    "abnormal",
    "abrasion",
    "abrasive",
    "abreast",
    "abridge",
    "abroad",
    "abruptly",
    "absence",
    "absentee",
    "absently",
    "absinthe",
    "absolute",
    "absolve",
    "abstain",
    "abstract",
    "absurd",
    "accent",
    "acclaim",
    "acclimate",
    "accompany",
    "account",
    "accuracy",
    "accurate",
    "accustom",
    "acetone",
    "achiness",
    "aching",
    "acid",
    "acorn",
    "acquaint",
    "acquire",
    "acre",
    "acrobat",
    "acronym",
    "acting",
    "action",
    "activate",
    "activator",
    "active",
    "activism",
    "activist",
    "activity",
    "actress",
    "acts",
    "acutely",
    "acuteness",
    "aeration",
    "aerobics",
    "aerosol",
    "aerospace",
    "afar",
    "affair",
    "affected",
    "affecting",
    "affection",
    "affidavit",
    "affiliate",
    "affirm",
    "affix",
    "afflicted",
    "affluent",
    "afford",
    "affront",
    "aflame",
    "afloat",
    "aflutter",
    "afoot",
    "afraid",
    "afterglow",
    "afterlife",
    "aftermath",
    "aftermost",
    "afternoon",
    "aged",
    "ageless",
    "agency",
    "agenda",
    "agent",
    "aggregate",
    "aghast",
    "agile",
    "agility",
    "aging",
    "agnostic",
    "agonize",
    "agonizing",
    "agony",
    "agreeable",
    "agreeably",
    "agreed",
    "agreeing",
    "agreement",
    "aground",
    "ahead",
    "ahoy",
    "aide",
    "aids",
    "aim",
    "ajar",
    "alabaster",
    "alarm",
    "albatross",
    "album",
    "alfalfa",
    "algebra",
    "algorithm",
    "alias",
    "alibi",
    "alienable",
    "alienate",
    "aliens",
    "alike",
    "alive",
    "alkaline",
    "alkalize",
    "almanac",
    "almighty",
    "almost",
    "aloe",
    "aloft",
    "aloha",
    "alone",
    "alongside",
    "aloof",
    "alphabet",
    "alright",
    "although",
    "altitude",
    "alto",
    "aluminum",
    "alumni",
    "always",
    "amaretto",
    "amaze",
    "amazingly",
    "amber",
    "ambiance",
    "ambiguity",
    "ambiguous",
    "ambition",
    "ambitious",
    "ambulance",
    "ambush",
    "amendable",
    "amendment",
    "amends",
    "amenity",
    "amiable",
    "amicably",
    "amid",
    "amigo",
    "amino",
    "amiss",
    "ammonia",
    "ammonium",
    "amnesty",
    "amniotic",
    "among",
    "amount",
    "amperage",
    "ample",
    "amplifier",
    "amplify",
    "amply",
    "amuck",
    "amulet",
    "amusable",
    "amused",
    "amusement",
    "amuser",
    "amusing",
    "anaconda",
    "anaerobic",
    "anagram",
    "anatomist",
    "anatomy",
    "anchor",
    "anchovy",
    "ancient",
    "android",
    "anemia",
    "anemic",
    "aneurism",
    "anew",
    "angelfish",
    "angelic",
    "anger",
    "angled",
    "angler",
    "angles",
    "angling",
    "angrily",
    "angriness",
    "anguished",
    "angular",
    "animal",
    "animate",
    "animating",
    "animation",
    "animator",
    "anime",
    "animosity",
    "ankle",
    "annex",
    "annotate",
    "announcer",
    "annoying",
    "annually",
    "annuity",
    "anointer",
    "another",
    "answering",
    "antacid",
    "antarctic",
    "anteater",
    "antelope",
    "antennae",
    "anthem",
    "anthill",
    "anthology",
    "antibody",
    "antics",
    "antidote",
    "antihero",
    "antiquely",
    "antiques",
    "antiquity",
    "antirust",
    "antitoxic",
    "antitrust",
    "antiviral",
    "antivirus",
    "antler",
    "antonym",
    "antsy",
    "anvil",
    "anybody",
    "anyhow",
    "anymore",
    "anyone",
    "anyplace",
    "anything",
    "anytime",
    "anyway",
    "anywhere",
    "aorta",
    "apache",
    "apostle",
    "appealing",
    "appear",
    "appease",
    "appeasing",
    "appendage",
    "appendix",
    "appetite",
    "appetizer",
    "applaud",
    "applause",
    "apple",
    "appliance",
    "applicant",
    "applied",
    "apply",
    "appointee",
    "appraisal",
    "appraiser",
    "apprehend",
    "approach",
    "approval",
    "approve",
    "apricot",
    "april",
    "apron",
    "aptitude",
    "aptly",
    "aqua",
    "aqueduct",
    "arbitrary",
    "arbitrate",
    "ardently",
    "area",
    "arena",
    "arguable",
    "arguably",
    "argue",
    "arise",
    "armadillo",
    "armband",
    "armchair",
    "armed",
    "armful",
    "armhole",
    "arming",
    "armless",
    "armoire",
    "armored",
    "armory",
    "armrest",
    "army",
    "aroma",
    "arose",
    "around",
    "arousal",
    "arrange",
    "array",
    "arrest",
    "arrival",
    "arrive",
    "arrogance",
    "arrogant",
    "arson",
    "art",
    "ascend",
    "ascension",
    "ascent",
    "ascertain",
    "ashamed",
    "ashen",
    "ashes",
    "ashy",
    "aside",
    "askew",
    "asleep",
    "asparagus",
    "aspect",
    "aspirate",
    "aspire",
    "aspirin",
    "astonish",
    "astound",
    "astride",
    "astrology",
    "astronaut",
    "astronomy",
    "astute",
    "atlantic",
    "atlas",
    "atom",
    "atonable",
    "atop",
    "atrium",
    "atrocious",
    "atrophy",
    "attach",
    "attain",
    "attempt",
    "attendant",
    "attendee",
    "attention",
    "attentive",
    "attest",
    "attic",
    "attire",
    "attitude",
    "attractor",
    "attribute",
    "atypical",
    "auction",
    "audacious",
    "audacity",
    "audible",
    "audibly",
    "audience",
    "audio",
    "audition",
    "augmented",
    "august",
    "authentic",
    "author",
    "autism",
    "autistic",
    "autograph",
    "automaker",
    "automated",
    "automatic",
    "autopilot",
    "available",
    "avalanche",
    "avatar",
    "avenge",
    "avenging",
    "avenue",
    "average",
    "aversion",
    "avert",
    "aviation",
    "aviator",
    "avid",
    "avoid",
    "await",
    "awaken",
    "award",
    "aware",
    "awhile",
    "awkward",
    "awning",
    "awoke",
    "awry",
    "axis",
    "babble",
    "babbling",
    "babied",
    "baboon",
    "backache",
    "backboard",
    "backboned",
    "backdrop",
    "backed",
    "backer",
    "backfield",
    "backfire",
    "backhand",
    "backing",
    "backlands",
    "backlash",
    "backless",
    "backlight",
    "backlit",
    "backlog",
    "backpack",
    "backpedal",
    "backrest",
    "backroom",
    "backshift",
    "backside",
    "backslid",
    "backspace",
    "backspin",
    "backstab",
    "backstage",
    "backtalk",
    "backtrack",
    "backup",
    "backward",
    "backwash",
    "backwater",
    "backyard",
    "bacon",
    "bacteria",
    "bacterium",
    "badass",
    "badge",
    "badland",
    "badly",
    "badness",
    "baffle",
    "baffling",
    "bagel",
    "bagful",
    "baggage",
    "bagged",
    "baggie",
    "bagginess",
    "bagging",
    "baggy",
    "bagpipe",
    "baguette",
    "baked",
    "bakery",
    "bakeshop",
    "baking",
    "balance",
    "balancing",
    "balcony",
    "balmy",
    "balsamic",
    "bamboo",
    "banana",
    "banish",
    "banister",
    "banjo",
    "bankable",
    "bankbook",
    "banked",
    "banker",
    "banking",
    "banknote",
    "bankroll",
    "banner",
    "bannister",
    "banshee",
    "banter",
    "barbecue",
    "barbed",
    "barbell",
    "barber",
    "barcode",
    "barge",
    "bargraph",
    "barista",
    "baritone",
    "barley",
    "barmaid",
    "barman",
    "barn",
    "barometer",
    "barrack",
    "barracuda",
    "barrel",
    "barrette",
    "barricade",
    "barrier",
    "barstool",
    "bartender",
    "barterer",
    "bash",
    "basically",
    "basics",
    "basil",
    "basin",
    "basis",
    "basket",
    "batboy",
    "batch",
    "bath",
    "baton",
    "bats",
    "battalion",
    "battered",
    "battering",
    "battery",
    "batting",
    "battle",
    "bauble",
    "bazooka",
    "blabber",
    "bladder",
    "blade",
    "blah",
    "blame",
    "blaming",
    "blanching",
    "blandness",
    "blank",
    "blaspheme",
    "blasphemy",
    "blast",
    "blatancy",
    "blatantly",
    "blazer",
    "blazing",
    "bleach",
    "bleak",
    "bleep",
    "blemish",
    "blend",
    "bless",
    "blighted",
    "blimp",
    "bling",
    "blinked",
    "blinker",
    "blinking",
    "blinks",
    "blip",
    "blissful",
    "blitz",
    "blizzard",
    "bloated",
    "bloating",
    "blob",
    "blog",
    "bloomers",
    "blooming",
    "blooper",
    "blot",
    "blouse",
    "blubber",
    "bluff",
    "bluish",
    "blunderer",
    "blunt",
    "blurb",
    "blurred",
    "blurry",
    "blurt",
    "blush",
    "blustery",
    "boaster",
    "boastful",
    "boasting",
    "boat",
    "bobbed",
    "bobbing",
    "bobble",
    "bobcat",
    "bobsled",
    "bobtail",
    "bodacious",
    "body",
    "bogged",
    "boggle",
    "bogus",
    "boil",
    "bok",
    "bolster",
    "bolt",
    "bonanza",
    "bonded",
    "bonding",
    "bondless",
    "boned",
    "bonehead",
    "boneless",
    "bonelike",
    "boney",
    "bonfire",
    "bonnet",
    "bonsai",
    "bonus",
    "bony",
    "boogeyman",
    "boogieman",
    "book",
    "boondocks",
    "booted",
    "booth",
    "bootie",
    "booting",
    "bootlace",
    "bootleg",
    "boots",
    "boozy",
    "borax",
    "boring",
    "borough",
    "borrower",
    "borrowing",
    "boss",
    "botanical",
    "botanist",
    "botany",
    "botch",
    "both",
    "bottle",
    "bottling",
    "bottom",
    "bounce",
    "bouncing",
    "bouncy",
    "bounding",
    "boundless",
    "bountiful",
    "bovine",
    "boxcar",
    "boxer",
    "boxing",
    "boxlike",
    "boxy",
    "breach",
    "breath",
    "breeches",
    "breeching",
    "breeder",
    "breeding",
    "breeze",
    "breezy",
    "brethren",
    "brewery",
    "brewing",
    "briar",
    "bribe",
    "brick",
    "bride",
    "bridged",
    "brigade",
    "bright",
    "brilliant",
    "brim",
    "bring",
    "brink",
    "brisket",
    "briskly",
    "briskness",
    "bristle",
    "brittle",
    "broadband",
    "broadcast",
    "broaden",
    "broadly",
    "broadness",
    "broadside",
    "broadways",
    "broiler",
    "broiling",
    "broken",
    "broker",
    "bronchial",
    "bronco",
    "bronze",
    "bronzing",
    "brook",
    "broom",
    "brought",
    "browbeat",
    "brownnose",
    "browse",
    "browsing",
    "bruising",
    "brunch",
    "brunette",
    "brunt",
    "brush",
    "brussels",
    "brute",
    "brutishly",
    "bubble",
    "bubbling",
    "bubbly",
    "buccaneer",
    "bucked",
    "bucket",
    "buckle",
    "buckshot",
    "buckskin",
    "bucktooth",
    "buckwheat",
    "buddhism",
    "buddhist",
    "budding",
    "buddy",
    "budget",
    "buffalo",
    "buffed",
    "buffer",
    "buffing",
    "buffoon",
    "buggy",
    "bulb",
    "bulge",
    "bulginess",
    "bulgur",
    "bulk",
    "bulldog",
    "bulldozer",
    "bullfight",
    "bullfrog",
    "bullhorn",
    "bullion",
    "bullish",
    "bullpen",
    "bullring",
    "bullseye",
    "bullwhip",
    "bully",
    "bunch",
    "bundle",
    "bungee",
    "bunion",
    "bunkbed",
    "bunkhouse",
    "bunkmate",
    "bunny",
    "bunt",
    "busboy",
    "bush",
    "busily",
    "busload",
    "bust",
    "busybody",
    "buzz",
    "cabana",
    "cabbage",
    "cabbie",
    "cabdriver",
    "cable",
    "caboose",
    "cache",
    "cackle",
    "cacti",
    "cactus",
    "caddie",
    "caddy",
    "cadet",
    "cadillac",
    "cadmium",
    "cage",
    "cahoots",
    "cake",
    "calamari",
    "calamity",
    "calcium",
    "calculate",
    "calculus",
    "caliber",
    "calibrate",
    "calm",
    "caloric",
    "calorie",
    "calzone",
    "camcorder",
    "cameo",
    "camera",
    "camisole",
    "camper",
    "campfire",
    "camping",
    "campsite",
    "campus",
    "canal",
    "canary",
    "cancel",
    "candied",
    "candle",
    "candy",
    "cane",
    "canine",
    "canister",
    "cannabis",
    "canned",
    "canning",
    "cannon",
    "cannot",
    "canola",
    "canon",
    "canopener",
    "canopy",
    "canteen",
    "canyon",
    "capable",
    "capably",
    "capacity",
    "cape",
    "capillary",
    "capital",
    "capitol",
    "capped",
    "capricorn",
    "capsize",
    "capsule",
    "caption",
    "captivate",
    "captive",
    "captivity",
    "capture",
    "caramel",
    "carat",
    "caravan",
    "carbon",
    "cardboard",
    "carded",
    "cardiac",
    "cardigan",
    "cardinal",
    "cardstock",
    "carefully",
    "caregiver",
    "careless",
    "caress",
    "caretaker",
    "cargo",
    "caring",
    "carless",
    "carload",
    "carmaker",
    "carnage",
    "carnation",
    "carnival",
    "carnivore",
    "carol",
    "carpenter",
    "carpentry",
    "carpool",
    "carport",
    "carried",
    "carrot",
    "carrousel",
    "carry",
    "cartel",
    "cartload",
    "carton",
    "cartoon",
    "cartridge",
    "cartwheel",
    "carve",
    "carving",
    "carwash",
    "cascade",
    "case",
    "cash",
    "casing",
    "casino",
    "casket",
    "cassette",
    "casually",
    "casualty",
    "catacomb",
    "catalog",
    "catalyst",
    "catalyze",
    "catapult",
    "cataract",
    "catatonic",
    "catcall",
    "catchable",
    "catcher",
    "catching",
    "catchy",
    "caterer",
    "catering",
    "catfight",
    "catfish",
    "cathedral",
    "cathouse",
    "catlike",
    "catnap",
    "catnip",
    "catsup",
    "cattail",
    "cattishly",
    "cattle",
    "catty",
    "catwalk",
    "caucasian",
    "caucus",
    "causal",
    "causation",
    "cause",
    "causing",
    "cauterize",
    "caution",
    "cautious",
    "cavalier",
    "cavalry",
    "caviar",
    "cavity",
    "cedar",
    "celery",
    "celestial",
    "celibacy",
    "celibate",
    "celtic",
    "cement",
    "census",
    "ceramics",
    "ceremony",
    "certainly",
    "certainty",
    "certified",
    "certify",
    "cesarean",
    "cesspool",
    "chafe",
    "chaffing",
    "chain",
    "chair",
    "chalice",
    "challenge",
    "chamber",
    "chamomile",
    "champion",
    "chance",
    "change",
    "channel",
    "chant",
    "chaos",
    "chaperone",
    "chaplain",
    "chapped",
    "chaps",
    "chapter",
    "character",
    "charbroil",
    "charcoal",
    "charger",
    "charging",
    "chariot",
    "charity",
    "charm",
    "charred",
    "charter",
    "charting",
    "chase",
    "chasing",
    "chaste",
    "chastise",
    "chastity",
    "chatroom",
    "chatter",
    "chatting",
    "chatty",
    "cheating",
    "cheddar",
    "cheek",
    "cheer",
    "cheese",
    "cheesy",
    "chef",
    "chemicals",
    "chemist",
    "chemo",
    "cherisher",
    "cherub",
    "chess",
    "chest",
    "chevron",
    "chevy",
    "chewable",
    "chewer",
    "chewing",
    "chewy",
    "chief",
    "chihuahua",
    "childcare",
    "childhood",
    "childish",
    "childless",
    "childlike",
    "chili",
    "chill",
    "chimp",
    "chip",
    "chirping",
    "chirpy",
    "chitchat",
    "chivalry",
    "chive",
    "chloride",
    "chlorine",
    "choice",
    "chokehold",
    "choking",
    "chomp",
    "chooser",
    "choosing",
    "choosy",
    "chop",
    "chosen",
    "chowder",
    "chowtime",
    "chrome",
    "chubby",
    "chuck",
    "chug",
    "chummy",
    "chump",
    "chunk",
    "churn",
    "chute",
    "cider",
    "cilantro",
    "cinch",
    "cinema",
    "cinnamon",
    "circle",
    "circling",
    "circular",
    "circulate",
    "circus",
    "citable",
    "citadel",
    "citation",
    "citizen",
    "citric",
    "citrus",
    "city",
    "civic",
    "civil",
    "clad",
    "claim",
    "clambake",
    "clammy",
    "clamor",
    "clamp",
    "clamshell",
    "clang",
    "clanking",
    "clapped",
    "clapper",
    "clapping",
    "clarify",
    "clarinet",
    "clarity",
    "clash",
    "clasp",
    "class",
    "clatter",
    "clause",
    "clavicle",
    "claw",
    "clay",
    "clean",
    "clear",
    "cleat",
    "cleaver",
    "cleft",
    "clench",
    "clergyman",
    "clerical",
    "clerk",
    "clever",
    "clicker",
    "client",
    "climate",
    "climatic",
    "cling",
    "clinic",
    "clinking",
    "clip",
    "clique",
    "cloak",
    "clobber",
    "clock",
    "clone",
    "cloning",
    "closable",
    "closure",
    "clothes",
    "clothing",
    "cloud",
    "clover",
    "clubbed",
    "clubbing",
    "clubhouse",
    "clump",
    "clumsily",
    "clumsy",
    "clunky",
    "clustered",
    "clutch",
    "clutter",
    "coach",
    "coagulant",
    "coastal",
    "coaster",
    "coasting",
    "coastland",
    "coastline",
    "coat",
    "coauthor",
    "cobalt",
    "cobbler",
    "cobweb",
    "cocoa",
    "coconut",
    "cod",
    "coeditor",
    "coerce",
    "coexist",
    "coffee",
    "cofounder",
    "cognition",
    "cognitive",
    "cogwheel",
    "coherence",
    "coherent",
    "cohesive",
    "coil",
    "coke",
    "cola",
    "cold",
    "coleslaw",
    "coliseum",
    "collage",
    "collapse",
    "collar",
    "collected",
    "collector",
    "collide",
    "collie",
    "collision",
    "colonial",
    "colonist",
    "colonize",
    "colony",
    "colossal",
    "colt",
    "coma",
    "come",
    "comfort",
    "comfy",
    "comic",
    "coming",
    "comma",
    "commence",
    "commend",
    "comment",
    "commerce",
    "commode",
    "commodity",
    "commodore",
    "common",
    "commotion",
    "commute",
    "commuting",
    "compacted",
    "compacter",
    "compactly",
    "compactor",
    "companion",
    "company",
    "compare",
    "compel",
    "compile",
    "comply",
    "component",
    "composed",
    "composer",
    "composite",
    "compost",
    "composure",
    "compound",
    "compress",
    "comprised",
    "computer",
    "computing",
    "comrade",
    "concave",
    "conceal",
    "conceded",
    "concept",
    "concerned",
    "concert",
    "conch",
    "concierge",
    "concise",
    "conclude",
    "concrete",
    "concur",
    "condense",
    "condiment",
    "condition",
    "condone",
    "conducive",
    "conductor",
    "conduit",
    "cone",
    "confess",
    "confetti",
    "confidant",
    "confident",
    "confider",
    "confiding",
    "configure",
    "confined",
    "confining",
    "confirm",
    "conflict",
    "conform",
    "confound",
    "confront",
    "confused",
    "confusing",
    "confusion",
    "congenial",
    "congested",
    "congrats",
    "congress",
    "conical",
    "conjoined",
    "conjure",
    "conjuror",
    "connected",
    "connector",
    "consensus",
    "consent",
    "console",
    "consoling",
    "consonant",
    "constable",
    "constant",
    "constrain",
    "constrict",
    "construct",
    "consult",
    "consumer",
    "consuming",
    "contact",
    "container",
    "contempt",
    "contend",
    "contented",
    "contently",
    "contents",
    "contest",
    "context",
    "contort",
    "contour",
    "contrite",
    "control",
    "contusion",
    "convene",
    "convent",
    "copartner",
    "cope",
    "copied",
    "copier",
    "copilot",
    "coping",
    "copious",
    "copper",
    "copy",
    "coral",
    "cork",
    "cornball",
    "cornbread",
    "corncob",
    "cornea",
    "corned",
    "corner",
    "cornfield",
    "cornflake",
    "cornhusk",
    "cornmeal",
    "cornstalk",
    "corny",
    "coronary",
    "coroner",
    "corporal",
    "corporate",
    "corral",
    "correct",
    "corridor",
    "corrode",
    "corroding",
    "corrosive",
    "corsage",
    "corset",
    "cortex",
    "cosigner",
    "cosmetics",
    "cosmic",
    "cosmos",
    "cosponsor",
    "cost",
    "cottage",
    "cotton",
    "couch",
    "cough",
    "could",
    "countable",
    "countdown",
    "counting",
    "countless",
    "country",
    "county",
    "courier",
    "covenant",
    "cover",
    "coveted",
    "coveting",
    "coyness",
    "cozily",
    "coziness",
    "cozy",
    "crabbing",
    "crabgrass",
    "crablike",
    "crabmeat",
    "cradle",
    "cradling",
    "crafter",
    "craftily",
    "craftsman",
    "craftwork",
    "crafty",
    "cramp",
    "cranberry",
    "crane",
    "cranial",
    "cranium",
    "crank",
    "crate",
    "crave",
    "craving",
    "crawfish",
    "crawlers",
    "crawling",
    "crayfish",
    "crayon",
    "crazed",
    "crazily",
    "craziness",
    "crazy",
    "creamed",
    "creamer",
    "creamlike",
    "crease",
    "creasing",
    "creatable",
    "create",
    "creation",
    "creative",
    "creature",
    "credible",
    "credibly",
    "credit",
    "creed",
    "creme",
    "creole",
    "crepe",
    "crept",
    "crescent",
    "crested",
    "cresting",
    "crestless",
    "crevice",
    "crewless",
    "crewman",
    "crewmate",
    "crib",
    "cricket",
    "cried",
    "crier",
    "crimp",
    "crimson",
    "cringe",
    "cringing",
    "crinkle",
    "crinkly",
    "crisped",
    "crisping",
    "crisply",
    "crispness",
    "crispy",
    "criteria",
    "critter",
    "croak",
    "crock",
    "crook",
    "croon",
    "crop",
    "cross",
    "crouch",
    "crouton",
    "crowbar",
    "crowd",
    "crown",
    "crucial",
    "crudely",
    "crudeness",
    "cruelly",
    "cruelness",
    "cruelty",
    "crumb",
    "crummiest",
    "crummy",
    "crumpet",
    "crumpled",
    "cruncher",
    "crunching",
    "crunchy",
    "crusader",
    "crushable",
    "crushed",
    "crusher",
    "crushing",
    "crust",
    "crux",
    "crying",
    "cryptic",
    "crystal",
    "cubbyhole",
    "cube",
    "cubical",
    "cubicle",
    "cucumber",
    "cuddle",
    "cuddly",
    "cufflink",
    "culinary",
    "culminate",
    "culpable",
    "culprit",
    "cultivate",
    "cultural",
    "culture",
    "cupbearer",
    "cupcake",
    "cupid",
    "cupped",
    "cupping",
    "curable",
    "curator",
    "curdle",
    "cure",
    "curfew",
    "curing",
    "curled",
    "curler",
    "curliness",
    "curling",
    "curly",
    "curry",
    "curse",
    "cursive",
    "cursor",
    "curtain",
    "curtly",
    "curtsy",
    "curvature",
    "curve",
    "curvy",
    "cushy",
    "cusp",
    "cussed",
    "custard",
    "custodian",
    "custody",
    "customary",
    "customer",
    "customize",
    "customs",
    "cut",
    "cycle",
    "cyclic",
    "cycling",
    "cyclist",
    "cylinder",
    "cymbal",
    "cytoplasm",
    "cytoplast",
    "dab",
    "dad",
    "daffodil",
    "dagger",
    "daily",
    "daintily",
    "dainty",
    "dairy",
    "daisy",
    "dallying",
    "dance",
    "dancing",
    "dandelion",
    "dander",
    "dandruff",
    "dandy",
    "danger",
    "dangle",
    "dangling",
    "daredevil",
    "dares",
    "daringly",
    "darkened",
    "darkening",
    "darkish",
    "darkness",
    "darkroom",
    "darling",
    "darn",
    "dart",
    "darwinism",
    "dash",
    "dastardly",
    "data",
    "datebook",
    "dating",
    "daughter",
    "daunting",
    "dawdler",
    "dawn",
    "daybed",
    "daybreak",
    "daycare",
    "daydream",
    "daylight",
    "daylong",
    "dayroom",
    "daytime",
    "dazzler",
    "dazzling",
    "deacon",
    "deafening",
    "deafness",
    "dealer",
    "dealing",
    "dealmaker",
    "dealt",
    "dean",
    "debatable",
    "debate",
    "debating",
    "debit",
    "debrief",
    "debtless",
    "debtor",
    "debug",
    "debunk",
    "decade",
    "decaf",
    "decal",
    "decathlon",
    "decay",
    "deceased",
    "deceit",
    "deceiver",
    "deceiving",
    "december",
    "decency",
    "decent",
    "deception",
    "deceptive",
    "decibel",
    "decidable",
    "decimal",
    "decimeter",
    "decipher",
    "deck",
    "declared",
    "decline",
    "decode",
    "decompose",
    "decorated",
    "decorator",
    "decoy",
    "decrease",
    "decree",
    "dedicate",
    "dedicator",
    "deduce",
    "deduct",
    "deed",
    "deem",
    "deepen",
    "deeply",
    "deepness",
    "deface",
    "defacing",
    "defame",
    "default",
    "defeat",
    "defection",
    "defective",
    "defendant",
    "defender",
    "defense",
    "defensive",
    "deferral",
    "deferred",
    "defiance",
    "defiant",
    "defile",
    "defiling",
    "define",
    "definite",
    "deflate",
    "deflation",
    "deflator",
    "deflected",
    "deflector",
    "defog",
    "deforest",
    "defraud",
    "defrost",
    "deftly",
    "defuse",
    "defy",
    "degraded",
    "degrading",
    "degrease",
    "degree",
    "dehydrate",
    "deity",
    "dejected",
    "delay",
    "delegate",
    "delegator",
    "delete",
    "deletion",
    "delicacy",
    "delicate",
    "delicious",
    "delighted",
    "delirious",
    "delirium",
    "deliverer",
    "delivery",
    "delouse",
    "delta",
    "deluge",
    "delusion",
    "deluxe",
    "demanding",
    "demeaning",
    "demeanor",
    "demise",
    "democracy",
    "democrat",
    "demote",
    "demotion",
    "demystify",
    "denatured",
    "deniable",
    "denial",
    "denim",
    "denote",
    "dense",
    "density",
    "dental",
    "dentist",
    "denture",
    "deny",
    "deodorant",
    "deodorize",
    "departed",
    "departure",
    "depict",
    "deplete",
    "depletion",
    "deplored",
    "deploy",
    "deport",
    "depose",
    "depraved",
    "depravity",
    "deprecate",
    "depress",
    "deprive",
    "depth",
    "deputize",
    "deputy",
    "derail",
    "deranged",
    "derby",
    "derived",
    "desecrate",
    "deserve",
    "deserving",
    "designate",
    "designed",
    "designer",
    "designing",
    "deskbound",
    "desktop",
    "deskwork",
    "desolate",
    "despair",
    "despise",
    "despite",
    "destiny",
    "destitute",
    "destruct",
    "detached",
    "detail",
    "detection",
    "detective",
    "detector",
    "detention",
    "detergent",
    "detest",
    "detonate",
    "detonator",
    "detoxify",
    "detract",
    "deuce",
    "devalue",
    "deviancy",
    "deviant",
    "deviate",
    "deviation",
    "deviator",
    "device",
    "devious",
    "devotedly",
    "devotee",
    "devotion",
    "devourer",
    "devouring",
    "devoutly",
    "dexterity",
    "dexterous",
    "diabetes",
    "diabetic",
    "diabolic",
    "diagnoses",
    "diagnosis",
    "diagram",
    "dial",
    "diameter",
    "diaper",
    "diaphragm",
    "diary",
    "dice",
    "dicing",
    "dictate",
    "dictation",
    "dictator",
    "difficult",
    "diffused",
    "diffuser",
    "diffusion",
    "diffusive",
    "dig",
    "dilation",
    "diligence",
    "diligent",
    "dill",
    "dilute",
    "dime",
    "diminish",
    "dimly",
    "dimmed",
    "dimmer",
    "dimness",
    "dimple",
    "diner",
    "dingbat",
    "dinghy",
    "dinginess",
    "dingo",
    "dingy",
    "dining",
    "dinner",
    "diocese",
    "dioxide",
    "diploma",
    "dipped",
    "dipper",
    "dipping",
    "directed",
    "direction",
    "directive",
    "directly",
    "directory",
    "direness",
    "dirtiness",
    "disabled",
    "disagree",
    "disallow",
    "disarm",
    "disarray",
    "disaster",
    "disband",
    "disbelief",
    "disburse",
    "discard",
    "discern",
    "discharge",
    "disclose",
    "discolor",
    "discount",
    "discourse",
    "discover",
    "discuss",
    "disdain",
    "disengage",
    "disfigure",
    "disgrace",
    "dish",
    "disinfect",
    "disjoin",
    "disk",
    "dislike",
    "disliking",
    "dislocate",
    "dislodge",
    "disloyal",
    "dismantle",
    "dismay",
    "dismiss",
    "dismount",
    "disobey",
    "disorder",
    "disown",
    "disparate",
    "disparity",
    "dispatch",
    "dispense",
    "dispersal",
    "dispersed",
    "disperser",
    "displace",
    "display",
    "displease",
    "disposal",
    "dispose",
    "disprove",
    "dispute",
    "disregard",
    "disrupt",
    "dissuade",
    "distance",
    "distant",
    "distaste",
    "distill",
    "distinct",
    "distort",
    "distract",
    "distress",
    "district",
    "distrust",
    "ditch",
    "ditto",
    "ditzy",
    "dividable",
    "divided",
    "dividend",
    "dividers",
    "dividing",
    "divinely",
    "diving",
    "divinity",
    "divisible",
    "divisibly",
    "division",
    "divisive",
    "divorcee",
    "dizziness",
    "dizzy",
    "doable",
    "docile",
    "dock",
    "doctrine",
    "document",
    "dodge",
    "dodgy",
    "doily",
    "doing",
    "dole",
    "dollar",
    "dollhouse",
    "dollop",
    "dolly",
    "dolphin",
    "domain",
    "domelike",
    "domestic",
    "dominion",
    "dominoes",
    "donated",
    "donation",
    "donator",
    "donor",
    "donut",
    "doodle",
    "doorbell",
    "doorframe",
    "doorknob",
    "doorman",
    "doormat",
    "doornail",
    "doorpost",
    "doorstep",
    "doorstop",
    "doorway",
    "doozy",
    "dork",
    "dormitory",
    "dorsal",
    "dosage",
    "dose",
    "dotted",
    "doubling",
    "douche",
    "dove",
    "down",
    "dowry",
    "doze",
    "drab",
    "dragging",
    "dragonfly",
    "dragonish",
    "dragster",
    "drainable",
    "drainage",
    "drained",
    "drainer",
    "drainpipe",
    "dramatic",
    "dramatize",
    "drank",
    "drapery",
    "drastic",
    "draw",
    "dreaded",
    "dreadful",
    "dreadlock",
    "dreamboat",
    "dreamily",
    "dreamland",
    "dreamless",
    "dreamlike",
    "dreamt",
    "dreamy",
    "drearily",
    "dreary",
    "drench",
    "dress",
    "drew",
    "dribble",
    "dried",
    "drier",
    "drift",
    "driller",
    "drilling",
    "drinkable",
    "drinking",
    "dripping",
    "drippy",
    "drivable",
    "driven",
    "driver",
    "driveway",
    "driving",
    "drizzle",
    "drizzly",
    "drone",
    "drool",
    "droop",
    "drop-down",
    "dropbox",
    "dropkick",
    "droplet",
    "dropout",
    "dropper",
    "drove",
    "drown",
    "drowsily",
    "drudge",
    "drum",
    "dry",
    "dubbed",
    "dubiously",
    "duchess",
    "duckbill",
    "ducking",
    "duckling",
    "ducktail",
    "ducky",
    "duct",
    "dude",
    "duffel",
    "dugout",
    "duh",
    "duke",
    "duller",
    "dullness",
    "duly",
    "dumping",
    "dumpling",
    "dumpster",
    "duo",
    "dupe",
    "duplex",
    "duplicate",
    "duplicity",
    "durable",
    "durably",
    "duration",
    "duress",
    "during",
    "dusk",
    "dust",
    "dutiful",
    "duty",
    "duvet",
    "dwarf",
    "dweeb",
    "dwelled",
    "dweller",
    "dwelling",
    "dwindle",
    "dwindling",
    "dynamic",
    "dynamite",
    "dynasty",
    "dyslexia",
    "dyslexic",
    "each",
    "eagle",
    "earache",
    "eardrum",
    "earflap",
    "earful",
    "earlobe",
    "early",
    "earmark",
    "earmuff",
    "earphone",
    "earpiece",
    "earplugs",
    "earring",
    "earshot",
    "earthen",
    "earthlike",
    "earthling",
    "earthly",
    "earthworm",
    "earthy",
    "earwig",
    "easeful",
    "easel",
    "easiest",
    "easily",
    "easiness",
    "easing",
    "eastbound",
    "eastcoast",
    "easter",
    "eastward",
    "eatable",
    "eaten",
    "eatery",
    "eating",
    "eats",
    "ebay",
    "ebony",
    "ebook",
    "ecard",
    "eccentric",
    "echo",
    "eclair",
    "eclipse",
    "ecologist",
    "ecology",
    "economic",
    "economist",
    "economy",
    "ecosphere",
    "ecosystem",
    "edge",
    "edginess",
    "edging",
    "edgy",
    "edition",
    "editor",
    "educated",
    "education",
    "educator",
    "eel",
    "effective",
    "effects",
    "efficient",
    "effort",
    "eggbeater",
    "egging",
    "eggnog",
    "eggplant",
    "eggshell",
    "egomaniac",
    "egotism",
    "egotistic",
    "either",
    "eject",
    "elaborate",
    "elastic",
    "elated",
    "elbow",
    "eldercare",
    "elderly",
    "eldest",
    "electable",
    "election",
    "elective",
    "elephant",
    "elevate",
    "elevating",
    "elevation",
    "elevator",
    "eleven",
    "elf",
    "eligible",
    "eligibly",
    "eliminate",
    "elite",
    "elitism",
    "elixir",
    "elk",
    "ellipse",
    "elliptic",
    "elm",
    "elongated",
    "elope",
    "eloquence",
    "eloquent",
    "elsewhere",
    "elude",
    "elusive",
    "elves",
    "email",
    "embargo",
    "embark",
    "embassy",
    "embattled",
    "embellish",
    "ember",
    "embezzle",
    "emblaze",
    "emblem",
    "embody",
    "embolism",
    "emboss",
    "embroider",
    "emcee",
    "emerald",
    "emergency",
    "emission",
    "emit",
    "emote",
    "emoticon",
    "emotion",
    "empathic",
    "empathy",
    "emperor",
    "emphases",
    "emphasis",
    "emphasize",
    "emphatic",
    "empirical",
    "employed",
    "employee",
    "employer",
    "emporium",
    "empower",
    "emptier",
    "emptiness",
    "empty",
    "emu",
    "enable",
    "enactment",
    "enamel",
    "enchanted",
    "enchilada",
    "encircle",
    "enclose",
    "enclosure",
    "encode",
    "encore",
    "encounter",
    "encourage",
    "encroach",
    "encrust",
    "encrypt",
    "endanger",
    "endeared",
    "endearing",
    "ended",
    "ending",
    "endless",
    "endnote",
    "endocrine",
    "endorphin",
    "endorse",
    "endowment",
    "endpoint",
    "endurable",
    "endurance",
    "enduring",
    "energetic",
    "energize",
    "energy",
    "enforced",
    "enforcer",
    "engaged",
    "engaging",
    "engine",
    "engorge",
    "engraved",
    "engraver",
    "engraving",
    "engross",
    "engulf",
    "enhance",
    "enigmatic",
    "enjoyable",
    "enjoyably",
    "enjoyer",
    "enjoying",
    "enjoyment",
    "enlarged",
    "enlarging",
    "enlighten",
    "enlisted",
    "enquirer",
    "enrage",
    "enrich",
    "enroll",
    "enslave",
    "ensnare",
    "ensure",
    "entail",
    "entangled",
    "entering",
    "entertain",
    "enticing",
    "entire",
    "entitle",
    "entity",
    "entomb",
    "entourage",
    "entrap",
    "entree",
    "entrench",
    "entrust",
    "entryway",
    "entwine",
    "enunciate",
    "envelope",
    "enviable",
    "enviably",
    "envious",
    "envision",
    "envoy",
    "envy",
    "enzyme",
    "epic",
    "epidemic",
    "epidermal",
    "epidermis",
    "epidural",
    "epilepsy",
    "epileptic",
    "epilogue",
    "epiphany",
    "episode",
    "equal",
    "equate",
    "equation",
    "equator",
    "equinox",
    "equipment",
    "equity",
    "equivocal",
    "eradicate",
    "erasable",
    "erased",
    "eraser",
    "erasure",
    "ergonomic",
    "errand",
    "errant",
    "erratic",
    "error",
    "erupt",
    "escalate",
    "escalator",
    "escapable",
    "escapade",
    "escapist",
    "escargot",
    "eskimo",
    "esophagus",
    "espionage",
    "espresso",
    "esquire",
    "essay",
    "essence",
    "essential",
    "establish",
    "estate",
    "esteemed",
    "estimate",
    "estimator",
    "estranged",
    "estrogen",
    "etching",
    "eternal",
    "eternity",
    "ethanol",
    "ether",
    "ethically",
    "ethics",
    "euphemism",
    "evacuate",
    "evacuee",
    "evade",
    "evaluate",
    "evaluator",
    "evaporate",
    "evasion",
    "evasive",
    "even",
    "everglade",
    "evergreen",
    "everybody",
    "everyday",
    "everyone",
    "evict",
    "evidence",
    "evident",
    "evil",
    "evoke",
    "evolution",
    "evolve",
    "exact",
    "exalted",
    "example",
    "excavate",
    "excavator",
    "exceeding",
    "exception",
    "excess",
    "exchange",
    "excitable",
    "exciting",
    "exclaim",
    "exclude",
    "excluding",
    "exclusion",
    "exclusive",
    "excretion",
    "excretory",
    "excursion",
    "excusable",
    "excusably",
    "excuse",
    "exemplary",
    "exemplify",
    "exemption",
    "exerciser",
    "exert",
    "exes",
    "exfoliate",
    "exhale",
    "exhaust",
    "exhume",
    "exile",
    "existing",
    "exit",
    "exodus",
    "exonerate",
    "exorcism",
    "exorcist",
    "expand",
    "expanse",
    "expansion",
    "expansive",
    "expectant",
    "expedited",
    "expediter",
    "expel",
    "expend",
    "expenses",
    "expensive",
    "expert",
    "expire",
    "expiring",
    "explain",
    "expletive",
    "explicit",
    "explode",
    "exploit",
    "explore",
    "exploring",
    "exponent",
    "exporter",
    "exposable",
    "expose",
    "exposure",
    "express",
    "expulsion",
    "exquisite",
    "extended",
    "extending",
    "extent",
    "extenuate",
    "exterior",
    "external",
    "extinct",
    "extortion",
    "extradite",
    "extras",
    "extrovert",
    "extrude",
    "extruding",
    "exuberant",
    "fable",
    "fabric",
    "fabulous",
    "facebook",
    "facecloth",
    "facedown",
    "faceless",
    "facelift",
    "faceplate",
    "faceted",
    "facial",
    "facility",
    "facing",
    "facsimile",
    "faction",
    "factoid",
    "factor",
    "factsheet",
    "factual",
    "faculty",
    "fade",
    "fading",
    "failing",
    "falcon",
    "fall",
    "false",
    "falsify",
    "fame",
    "familiar",
    "family",
    "famine",
    "famished",
    "fanatic",
    "fancied",
    "fanciness",
    "fancy",
    "fanfare",
    "fang",
    "fanning",
    "fantasize",
    "fantastic",
    "fantasy",
    "fascism",
    "fastball",
    "faster",
    "fasting",
    "fastness",
    "faucet",
    "favorable",
    "favorably",
    "favored",
    "favoring",
    "favorite",
    "fax",
    "feast",
    "federal",
    "fedora",
    "feeble",
    "feed",
    "feel",
    "feisty",
    "feline",
    "felt-tip",
    "feminine",
    "feminism",
    "feminist",
    "feminize",
    "femur",
    "fence",
    "fencing",
    "fender",
    "ferment",
    "fernlike",
    "ferocious",
    "ferocity",
    "ferret",
    "ferris",
    "ferry",
    "fervor",
    "fester",
    "festival",
    "festive",
    "festivity",
    "fetal",
    "fetch",
    "fever",
    "fiber",
    "fiction",
    "fiddle",
    "fiddling",
    "fidelity",
    "fidgeting",
    "fidgety",
    "fifteen",
    "fifth",
    "fiftieth",
    "fifty",
    "figment",
    "figure",
    "figurine",
    "filing",
    "filled",
    "filler",
    "filling",
    "film",
    "filter",
    "filth",
    "filtrate",
    "finale",
    "finalist",
    "finalize",
    "finally",
    "finance",
    "financial",
    "finch",
    "fineness",
    "finer",
    "finicky",
    "finished",
    "finisher",
    "finishing",
    "finite",
    "finless",
    "finlike",
    "fiscally",
    "fit",
    "five",
    "flaccid",
    "flagman",
    "flagpole",
    "flagship",
    "flagstick",
    "flagstone",
    "flail",
    "flakily",
    "flaky",
    "flame",
    "flammable",
    "flanked",
    "flanking",
    "flannels",
    "flap",
    "flaring",
    "flashback",
    "flashbulb",
    "flashcard",
    "flashily",
    "flashing",
    "flashy",
    "flask",
    "flatbed",
    "flatfoot",
    "flatly",
    "flatness",
    "flatten",
    "flattered",
    "flatterer",
    "flattery",
    "flattop",
    "flatware",
    "flatworm",
    "flavored",
    "flavorful",
    "flavoring",
    "flaxseed",
    "fled",
    "fleshed",
    "fleshy",
    "flick",
    "flier",
    "flight",
    "flinch",
    "fling",
    "flint",
    "flip",
    "flirt",
    "float",
    "flock",
    "flogging",
    "flop",
    "floral",
    "florist",
    "floss",
    "flounder",
    "flyable",
    "flyaway",
    "flyer",
    "flying",
    "flyover",
    "flypaper",
    "foam",
    "foe",
    "fog",
    "foil",
    "folic",
    "folk",
    "follicle",
    "follow",
    "fondling",
    "fondly",
    "fondness",
    "fondue",
    "font",
    "food",
    "fool",
    "footage",
    "football",
    "footbath",
    "footboard",
    "footer",
    "footgear",
    "foothill",
    "foothold",
    "footing",
    "footless",
    "footman",
    "footnote",
    "footpad",
    "footpath",
    "footprint",
    "footrest",
    "footsie",
    "footsore",
    "footwear",
    "footwork",
    "fossil",
    "foster",
    "founder",
    "founding",
    "fountain",
    "fox",
    "foyer",
    "fraction",
    "fracture",
    "fragile",
    "fragility",
    "fragment",
    "fragrance",
    "fragrant",
    "frail",
    "frame",
    "framing",
    "frantic",
    "fraternal",
    "frayed",
    "fraying",
    "frays",
    "freckled",
    "freckles",
    "freebase",
    "freebee",
    "freebie",
    "freedom",
    "freefall",
    "freehand",
    "freeing",
    "freeload",
    "freely",
    "freemason",
    "freeness",
    "freestyle",
    "freeware",
    "freeway",
    "freewill",
    "freezable",
    "freezing",
    "freight",
    "french",
    "frenzied",
    "frenzy",
    "frequency",
    "frequent",
    "fresh",
    "fretful",
    "fretted",
    "friction",
    "friday",
    "fridge",
    "fried",
    "friend",
    "frighten",
    "frightful",
    "frigidity",
    "frigidly",
    "frill",
    "fringe",
    "frisbee",
    "frisk",
    "fritter",
    "frivolous",
    "frolic",
    "from",
    "front",
    "frostbite",
    "frosted",
    "frostily",
    "frosting",
    "frostlike",
    "frosty",
    "froth",
    "frown",
    "frozen",
    "fructose",
    "frugality",
    "frugally",
    "fruit",
    "frustrate",
    "frying",
    "gab",
    "gaffe",
    "gag",
    "gainfully",
    "gaining",
    "gains",
    "gala",
    "gallantly",
    "galleria",
    "gallery",
    "galley",
    "gallon",
    "gallows",
    "gallstone",
    "galore",
    "galvanize",
    "gambling",
    "game",
    "gaming",
    "gamma",
    "gander",
    "gangly",
    "gangrene",
    "gangway",
    "gap",
    "garage",
    "garbage",
    "garden",
    "gargle",
    "garland",
    "garlic",
    "garment",
    "garnet",
    "garnish",
    "garter",
    "gas",
    "gatherer",
    "gathering",
    "gating",
    "gauging",
    "gauntlet",
    "gauze",
    "gave",
    "gawk",
    "gazing",
    "gear",
    "gecko",
    "geek",
    "geiger",
    "gem",
    "gender",
    "generic",
    "generous",
    "genetics",
    "genre",
    "gentile",
    "gentleman",
    "gently",
    "gents",
    "geography",
    "geologic",
    "geologist",
    "geology",
    "geometric",
    "geometry",
    "geranium",
    "gerbil",
    "geriatric",
    "germicide",
    "germinate",
    "germless",
    "germproof",
    "gestate",
    "gestation",
    "gesture",
    "getaway",
    "getting",
    "getup",
    "giant",
    "gibberish",
    "giblet",
    "giddily",
    "giddiness",
    "giddy",
    "gift",
    "gigabyte",
    "gigahertz",
    "gigantic",
    "giggle",
    "giggling",
    "giggly",
    "gigolo",
    "gilled",
    "gills",
    "gimmick",
    "girdle",
    "giveaway",
    "given",
    "giver",
    "giving",
    "gizmo",
    "gizzard",
    "glacial",
    "glacier",
    "glade",
    "gladiator",
    "gladly",
    "glamorous",
    "glamour",
    "glance",
    "glancing",
    "glandular",
    "glare",
    "glaring",
    "glass",
    "glaucoma",
    "glazing",
    "gleaming",
    "gleeful",
    "glider",
    "gliding",
    "glimmer",
    "glimpse",
    "glisten",
    "glitch",
    "glitter",
    "glitzy",
    "gloater",
    "gloating",
    "gloomily",
    "gloomy",
    "glorified",
    "glorifier",
    "glorify",
    "glorious",
    "glory",
    "gloss",
    "glove",
    "glowing",
    "glowworm",
    "glucose",
    "glue",
    "gluten",
    "glutinous",
    "glutton",
    "gnarly",
    "gnat",
    "goal",
    "goatskin",
    "goes",
    "goggles",
    "going",
    "goldfish",
    "goldmine",
    "goldsmith",
    "golf",
    "goliath",
    "gonad",
    "gondola",
    "gone",
    "gong",
    "good",
    "gooey",
    "goofball",
    "goofiness",
    "goofy",
    "google",
    "goon",
    "gopher",
    "gore",
    "gorged",
    "gorgeous",
    "gory",
    "gosling",
    "gossip",
    "gothic",
    "gotten",
    "gout",
    "gown",
    "grab",
    "graceful",
    "graceless",
    "gracious",
    "gradation",
    "graded",
    "grader",
    "gradient",
    "grading",
    "gradually",
    "graduate",
    "graffiti",
    "grafted",
    "grafting",
    "grain",
    "granddad",
    "grandkid",
    "grandly",
    "grandma",
    "grandpa",
    "grandson",
    "granite",
    "granny",
    "granola",
    "grant",
    "granular",
    "grape",
    "graph",
    "grapple",
    "grappling",
    "grasp",
    "grass",
    "gratified",
    "gratify",
    "grating",
    "gratitude",
    "gratuity",
    "gravel",
    "graveness",
    "graves",
    "graveyard",
    "gravitate",
    "gravity",
    "gravy",
    "gray",
    "grazing",
    "greasily",
    "greedily",
    "greedless",
    "greedy",
    "green",
    "greeter",
    "greeting",
    "grew",
    "greyhound",
    "grid",
    "grief",
    "grievance",
    "grieving",
    "grievous",
    "grill",
    "grimace",
    "grimacing",
    "grime",
    "griminess",
    "grimy",
    "grinch",
    "grinning",
    "grip",
    "gristle",
    "grit",
    "groggily",
    "groggy",
    "groin",
    "groom",
    "groove",
    "grooving",
    "groovy",
    "grope",
    "ground",
    "grouped",
    "grout",
    "grove",
    "grower",
    "growing",
    "growl",
    "grub",
    "grudge",
    "grudging",
    "grueling",
    "gruffly",
    "grumble",
    "grumbling",
    "grumbly",
    "grumpily",
    "grunge",
    "grunt",
    "guacamole",
    "guidable",
    "guidance",
    "guide",
    "guiding",
    "guileless",
    "guise",
    "gulf",
    "gullible",
    "gully",
    "gulp",
    "gumball",
    "gumdrop",
    "gumminess",
    "gumming",
    "gummy",
    "gurgle",
    "gurgling",
    "guru",
    "gush",
    "gusto",
    "gusty",
    "gutless",
    "guts",
    "gutter",
    "guy",
    "guzzler",
    "gyration",
    "habitable",
    "habitant",
    "habitat",
    "habitual",
    "hacked",
    "hacker",
    "hacking",
    "hacksaw",
    "had",
    "haggler",
    "haiku",
    "half",
    "halogen",
    "halt",
    "halved",
    "halves",
    "hamburger",
    "hamlet",
    "hammock",
    "hamper",
    "hamster",
    "hamstring",
    "handbag",
    "handball",
    "handbook",
    "handbrake",
    "handcart",
    "handclap",
    "handclasp",
    "handcraft",
    "handcuff",
    "handed",
    "handful",
    "handgrip",
    "handgun",
    "handheld",
    "handiness",
    "handiwork",
    "handlebar",
    "handled",
    "handler",
    "handling",
    "handmade",
    "handoff",
    "handpick",
    "handprint",
    "handrail",
    "handsaw",
    "handset",
    "handsfree",
    "handshake",
    "handstand",
    "handwash",
    "handwork",
    "handwoven",
    "handwrite",
    "handyman",
    "hangnail",
    "hangout",
    "hangover",
    "hangup",
    "hankering",
    "hankie",
    "hanky",
    "haphazard",
    "happening",
    "happier",
    "happiest",
    "happily",
    "happiness",
    "happy",
    "harbor",
    "hardcopy",
    "hardcore",
    "hardcover",
    "harddisk",
    "hardened",
    "hardener",
    "hardening",
    "hardhat",
    "hardhead",
    "hardiness",
    "hardly",
    "hardness",
    "hardship",
    "hardware",
    "hardwired",
    "hardwood",
    "hardy",
    "harmful",
    "harmless",
    "harmonica",
    "harmonics",
    "harmonize",
    "harmony",
    "harness",
    "harpist",
    "harsh",
    "harvest",
    "hash",
    "hassle",
    "haste",
    "hastily",
    "hastiness",
    "hasty",
    "hatbox",
    "hatchback",
    "hatchery",
    "hatchet",
    "hatching",
    "hatchling",
    "hate",
    "hatless",
    "hatred",
    "haunt",
    "haven",
    "hazard",
    "hazelnut",
    "hazily",
    "haziness",
    "hazing",
    "hazy",
    "headache",
    "headband",
    "headboard",
    "headcount",
    "headdress",
    "headed",
    "header",
    "headfirst",
    "headgear",
    "heading",
    "headlamp",
    "headless",
    "headlock",
    "headphone",
    "headpiece",
    "headrest",
    "headroom",
    "headscarf",
    "headset",
    "headsman",
    "headstand",
    "headstone",
    "headway",
    "headwear",
    "heap",
    "heat",
    "heave",
    "heavily",
    "heaviness",
    "heaving",
    "hedge",
    "hedging",
    "heftiness",
    "hefty",
    "helium",
    "helmet",
    "helper",
    "helpful",
    "helping",
    "helpless",
    "helpline",
    "hemlock",
    "hemstitch",
    "hence",
    "henchman",
    "henna",
    "herald",
    "herbal",
    "herbicide",
    "herbs",
    "heritage",
    "hermit",
    "heroics",
    "heroism",
    "herring",
    "herself",
    "hertz",
    "hesitancy",
    "hesitant",
    "hesitate",
    "hexagon",
    "hexagram",
    "hubcap",
    "huddle",
    "huddling",
    "huff",
    "hug",
    "hula",
    "hulk",
    "hull",
    "human",
    "humble",
    "humbling",
    "humbly",
    "humid",
    "humiliate",
    "humility",
    "humming",
    "hummus",
    "humongous",
    "humorist",
    "humorless",
    "humorous",
    "humpback",
    "humped",
    "humvee",
    "hunchback",
    "hundredth",
    "hunger",
    "hungrily",
    "hungry",
    "hunk",
    "hunter",
    "hunting",
    "huntress",
    "huntsman",
    "hurdle",
    "hurled",
    "hurler",
    "hurling",
    "hurray",
    "hurricane",
    "hurried",
    "hurry",
    "hurt",
    "husband",
    "hush",
    "husked",
    "huskiness",
    "hut",
    "hybrid",
    "hydrant",
    "hydrated",
    "hydration",
    "hydrogen",
    "hydroxide",
    "hyperlink",
    "hypertext",
    "hyphen",
    "hypnoses",
    "hypnosis",
    "hypnotic",
    "hypnotism",
    "hypnotist",
    "hypnotize",
    "hypocrisy",
    "hypocrite",
    "ibuprofen",
    "ice",
    "iciness",
    "icing",
    "icky",
    "icon",
    "icy",
    "idealism",
    "idealist",
    "idealize",
    "ideally",
    "idealness",
    "identical",
    "identify",
    "identity",
    "ideology",
    "idiocy",
    "idiom",
    "idly",
    "igloo",
    "ignition",
    "ignore",
    "iguana",
    "illicitly",
    "illusion",
    "illusive",
    "image",
    "imaginary",
    "imagines",
    "imaging",
    "imbecile",
    "imitate",
    "imitation",
    "immature",
    "immerse",
    "immersion",
    "imminent",
    "immobile",
    "immodest",
    "immorally",
    "immortal",
    "immovable",
    "immovably",
    "immunity",
    "immunize",
    "impaired",
    "impale",
    "impart",
    "impatient",
    "impeach",
    "impeding",
    "impending",
    "imperfect",
    "imperial",
    "impish",
    "implant",
    "implement",
    "implicate",
    "implicit",
    "implode",
    "implosion",
    "implosive",
    "imply",
    "impolite",
    "important",
    "importer",
    "impose",
    "imposing",
    "impotence",
    "impotency",
    "impotent",
    "impound",
    "imprecise",
    "imprint",
    "imprison",
    "impromptu",
    "improper",
    "improve",
    "improving",
    "improvise",
    "imprudent",
    "impulse",
    "impulsive",
    "impure",
    "impurity",
    "iodine",
    "iodize",
    "ion",
    "ipad",
    "iphone",
    "ipod",
    "irate",
    "irk",
    "iron",
    "irregular",
    "irrigate",
    "irritable",
    "irritably",
    "irritant",
    "irritate",
    "islamic",
    "islamist",
    "isolated",
    "isolating",
    "isolation",
    "isotope",
    "issue",
    "issuing",
    "italicize",
    "italics",
    "item",
    "itinerary",
    "itunes",
    "ivory",
    "ivy",
    "jab",
    "jackal",
    "jacket",
    "jackknife",
    "jackpot",
    "jailbird",
    "jailbreak",
    "jailer",
    "jailhouse",
    "jalapeno",
    "jam",
    "janitor",
    "january",
    "jargon",
    "jarring",
    "jasmine",
    "jaundice",
    "jaunt",
    "java",
    "jawed",
    "jawless",
    "jawline",
    "jaws",
    "jaybird",
    "jaywalker",
    "jazz",
    "jeep",
    "jeeringly",
    "jellied",
    "jelly",
    "jersey",
    "jester",
    "jet",
    "jiffy",
    "jigsaw",
    "jimmy",
    "jingle",
    "jingling",
    "jinx",
    "jitters",
    "jittery",
    "job",
    "jockey",
    "jockstrap",
    "jogger",
    "jogging",
    "john",
    "joining",
    "jokester",
    "jokingly",
    "jolliness",
    "jolly",
    "jolt",
    "jot",
    "jovial",
    "joyfully",
    "joylessly",
    "joyous",
    "joyride",
    "joystick",
    "jubilance",
    "jubilant",
    "judge",
    "judgingly",
    "judicial",
    "judiciary",
    "judo",
    "juggle",
    "juggling",
    "jugular",
    "juice",
    "juiciness",
    "juicy",
    "jujitsu",
    "jukebox",
    "july",
    "jumble",
    "jumbo",
    "jump",
    "junction",
    "juncture",
    "june",
    "junior",
    "juniper",
    "junkie",
    "junkman",
    "junkyard",
    "jurist",
    "juror",
    "jury",
    "justice",
    "justifier",
    "justify",
    "justly",
    "justness",
    "juvenile",
    "kabob",
    "kangaroo",
    "karaoke",
    "karate",
    "karma",
    "kebab",
    "keenly",
    "keenness",
    "keep",
    "keg",
    "kelp",
    "kennel",
    "kept",
    "kerchief",
    "kerosene",
    "kettle",
    "kick",
    "kiln",
    "kilobyte",
    "kilogram",
    "kilometer",
    "kilowatt",
    "kilt",
    "kimono",
    "kindle",
    "kindling",
    "kindly",
    "kindness",
    "kindred",
    "kinetic",
    "kinfolk",
    "king",
    "kinship",
    "kinsman",
    "kinswoman",
    "kissable",
    "kisser",
    "kissing",
    "kitchen",
    "kite",
    "kitten",
    "kitty",
    "kiwi",
    "kleenex",
    "knapsack",
    "knee",
    "knelt",
    "knickers",
    "knoll",
    "koala",
    "kooky",
    "kosher",
    "krypton",
    "kudos",
    "kung",
    "labored",
    "laborer",
    "laboring",
    "laborious",
    "labrador",
    "ladder",
    "ladies",
    "ladle",
    "ladybug",
    "ladylike",
    "lagged",
    "lagging",
    "lagoon",
    "lair",
    "lake",
    "lance",
    "landed",
    "landfall",
    "landfill",
    "landing",
    "landlady",
    "landless",
    "landline",
    "landlord",
    "landmark",
    "landmass",
    "landmine",
    "landowner",
    "landscape",
    "landside",
    "landslide",
    "language",
    "lankiness",
    "lanky",
    "lantern",
    "lapdog",
    "lapel",
    "lapped",
    "lapping",
    "laptop",
    "lard",
    "large",
    "lark",
    "lash",
    "lasso",
    "last",
    "latch",
    "late",
    "lather",
    "latitude",
    "latrine",
    "latter",
    "latticed",
    "launch",
    "launder",
    "laundry",
    "laurel",
    "lavender",
    "lavish",
    "laxative",
    "lazily",
    "laziness",
    "lazy",
    "lecturer",
    "left",
    "legacy",
    "legal",
    "legend",
    "legged",
    "leggings",
    "legible",
    "legibly",
    "legislate",
    "lego",
    "legroom",
    "legume",
    "legwarmer",
    "legwork",
    "lemon",
    "lend",
    "length",
    "lens",
    "lent",
    "leotard",
    "lesser",
    "letdown",
    "lethargic",
    "lethargy",
    "letter",
    "lettuce",
    "level",
    "leverage",
    "levers",
    "levitate",
    "levitator",
    "liability",
    "liable",
    "liberty",
    "librarian",
    "library",
    "licking",
    "licorice",
    "lid",
    "life",
    "lifter",
    "lifting",
    "liftoff",
    "ligament",
    "likely",
    "likeness",
    "likewise",
    "liking",
    "lilac",
    "lilly",
    "lily",
    "limb",
    "limeade",
    "limelight",
    "limes",
    "limit",
    "limping",
    "limpness",
    "line",
    "lingo",
    "linguini",
    "linguist",
    "lining",
    "linked",
    "linoleum",
    "linseed",
    "lint",
    "lion",
    "lip",
    "liquefy",
    "liqueur",
    "liquid",
    "lisp",
    "list",
    "litigate",
    "litigator",
    "litmus",
    "litter",
    "little",
    "livable",
    "lived",
    "lively",
    "liver",
    "livestock",
    "lividly",
    "living",
    "lizard",
    "lubricant",
    "lubricate",
    "lucid",
    "luckily",
    "luckiness",
    "luckless",
    "lucrative",
    "ludicrous",
    "lugged",
    "lukewarm",
    "lullaby",
    "lumber",
    "luminance",
    "luminous",
    "lumpiness",
    "lumping",
    "lumpish",
    "lunacy",
    "lunar",
    "lunchbox",
    "luncheon",
    "lunchroom",
    "lunchtime",
    "lung",
    "lurch",
    "lure",
    "luridness",
    "lurk",
    "lushly",
    "lushness",
    "luster",
    "lustfully",
    "lustily",
    "lustiness",
    "lustrous",
    "lusty",
    "luxurious",
    "luxury",
    "lying",
    "lyrically",
    "lyricism",
    "lyricist",
    "lyrics",
    "macarena",
    "macaroni",
    "macaw",
    "mace",
    "machine",
    "machinist",
    "magazine",
    "magenta",
    "maggot",
    "magical",
    "magician",
    "magma",
    "magnesium",
    "magnetic",
    "magnetism",
    "magnetize",
    "magnifier",
    "magnify",
    "magnitude",
    "magnolia",
    "mahogany",
    "maimed",
    "majestic",
    "majesty",
    "majorette",
    "majority",
    "makeover",
    "maker",
    "makeshift",
    "making",
    "malformed",
    "malt",
    "mama",
    "mammal",
    "mammary",
    "mammogram",
    "manager",
    "managing",
    "manatee",
    "mandarin",
    "mandate",
    "mandatory",
    "mandolin",
    "manger",
    "mangle",
    "mango",
    "mangy",
    "manhandle",
    "manhole",
    "manhood",
    "manhunt",
    "manicotti",
    "manicure",
    "manifesto",
    "manila",
    "mankind",
    "manlike",
    "manliness",
    "manly",
    "manmade",
    "manned",
    "mannish",
    "manor",
    "manpower",
    "mantis",
    "mantra",
    "manual",
    "many",
    "map",
    "marathon",
    "marauding",
    "marbled",
    "marbles",
    "marbling",
    "march",
    "mardi",
    "margarine",
    "margarita",
    "margin",
    "marigold",
    "marina",
    "marine",
    "marital",
    "maritime",
    "marlin",
    "marmalade",
    "maroon",
    "married",
    "marrow",
    "marry",
    "marshland",
    "marshy",
    "marsupial",
    "marvelous",
    "marxism",
    "mascot",
    "masculine",
    "mashed",
    "mashing",
    "massager",
    "masses",
    "massive",
    "mastiff",
    "matador",
    "matchbook",
    "matchbox",
    "matcher",
    "matching",
    "matchless",
    "material",
    "maternal",
    "maternity",
    "math",
    "mating",
    "matriarch",
    "matrimony",
    "matrix",
    "matron",
    "matted",
    "matter",
    "maturely",
    "maturing",
    "maturity",
    "mauve",
    "maverick",
    "maximize",
    "maximum",
    "maybe",
    "mayday",
    "mayflower",
    "moaner",
    "moaning",
    "mobile",
    "mobility",
    "mobilize",
    "mobster",
    "mocha",
    "mocker",
    "mockup",
    "modified",
    "modify",
    "modular",
    "modulator",
    "module",
    "moisten",
    "moistness",
    "moisture",
    "molar",
    "molasses",
    "mold",
    "molecular",
    "molecule",
    "molehill",
    "mollusk",
    "mom",
    "monastery",
    "monday",
    "monetary",
    "monetize",
    "moneybags",
    "moneyless",
    "moneywise",
    "mongoose",
    "mongrel",
    "monitor",
    "monkhood",
    "monogamy",
    "monogram",
    "monologue",
    "monopoly",
    "monorail",
    "monotone",
    "monotype",
    "monoxide",
    "monsieur",
    "monsoon",
    "monstrous",
    "monthly",
    "monument",
    "moocher",
    "moodiness",
    "moody",
    "mooing",
    "moonbeam",
    "mooned",
    "moonlight",
    "moonlike",
    "moonlit",
    "moonrise",
    "moonscape",
    "moonshine",
    "moonstone",
    "moonwalk",
    "mop",
    "morale",
    "morality",
    "morally",
    "morbidity",
    "morbidly",
    "morphine",
    "morphing",
    "morse",
    "mortality",
    "mortally",
    "mortician",
    "mortified",
    "mortify",
    "mortuary",
    "mosaic",
    "mossy",
    "most",
    "mothball",
    "mothproof",
    "motion",
    "motivate",
    "motivator",
    "motive",
    "motocross",
    "motor",
    "motto",
    "mountable",
    "mountain",
    "mounted",
    "mounting",
    "mourner",
    "mournful",
    "mouse",
    "mousiness",
    "moustache",
    "mousy",
    "mouth",
    "movable",
    "move",
    "movie",
    "moving",
    "mower",
    "mowing",
    "much",
    "muck",
    "mud",
    "mug",
    "mulberry",
    "mulch",
    "mule",
    "mulled",
    "mullets",
    "multiple",
    "multiply",
    "multitask",
    "multitude",
    "mumble",
    "mumbling",
    "mumbo",
    "mummified",
    "mummify",
    "mummy",
    "mumps",
    "munchkin",
    "mundane",
    "municipal",
    "muppet",
    "mural",
    "murkiness",
    "murky",
    "murmuring",
    "muscular",
    "museum",
    "mushily",
    "mushiness",
    "mushroom",
    "mushy",
    "music",
    "musket",
    "muskiness",
    "musky",
    "mustang",
    "mustard",
    "muster",
    "mustiness",
    "musty",
    "mutable",
    "mutate",
    "mutation",
    "mute",
    "mutilated",
    "mutilator",
    "mutiny",
    "mutt",
    "mutual",
    "muzzle",
    "myself",
    "myspace",
    "mystified",
    "mystify",
    "myth",
    "nacho",
    "nag",
    "nail",
    "name",
    "naming",
    "nanny",
    "nanometer",
    "nape",
    "napkin",
    "napped",
    "napping",
    "nappy",
    "narrow",
    "nastily",
    "nastiness",
    "national",
    "native",
    "nativity",
    "natural",
    "nature",
    "naturist",
    "nautical",
    "navigate",
    "navigator",
    "navy",
    "nearby",
    "nearest",
    "nearly",
    "nearness",
    "neatly",
    "neatness",
    "nebula",
    "nebulizer",
    "nectar",
    "negate",
    "negation",
    "negative",
    "neglector",
    "negligee",
    "negligent",
    "negotiate",
    "nemeses",
    "nemesis",
    "neon",
    "nephew",
    "nerd",
    "nervous",
    "nervy",
    "nest",
    "net",
    "neurology",
    "neuron",
    "neurosis",
    "neurotic",
    "neuter",
    "neutron",
    "never",
    "next",
    "nibble",
    "nickname",
    "nicotine",
    "niece",
    "nifty",
    "nimble",
    "nimbly",
    "nineteen",
    "ninetieth",
    "ninja",
    "nintendo",
    "ninth",
    "nuclear",
    "nuclei",
    "nucleus",
    "nugget",
    "nullify",
    "number",
    "numbing",
    "numbly",
    "numbness",
    "numeral",
    "numerate",
    "numerator",
    "numeric",
    "numerous",
    "nuptials",
    "nursery",
    "nursing",
    "nurture",
    "nutcase",
    "nutlike",
    "nutmeg",
    "nutrient",
    "nutshell",
    "nuttiness",
    "nutty",
    "nuzzle",
    "nylon",
    "oaf",
    "oak",
    "oasis",
    "oat",
    "obedience",
    "obedient",
    "obituary",
    "object",
    "obligate",
    "obliged",
    "oblivion",
    "oblivious",
    "oblong",
    "obnoxious",
    "oboe",
    "obscure",
    "obscurity",
    "observant",
    "observer",
    "observing",
    "obsessed",
    "obsession",
    "obsessive",
    "obsolete",
    "obstacle",
    "obstinate",
    "obstruct",
    "obtain",
    "obtrusive",
    "obtuse",
    "obvious",
    "occultist",
    "occupancy",
    "occupant",
    "occupier",
    "occupy",
    "ocean",
    "ocelot",
    "octagon",
    "octane",
    "october",
    "octopus",
    "ogle",
    "oil",
    "oink",
    "ointment",
    "okay",
    "old",
    "olive",
    "olympics",
    "omega",
    "omen",
    "ominous",
    "omission",
    "omit",
    "omnivore",
    "onboard",
    "oncoming",
    "ongoing",
    "onion",
    "online",
    "onlooker",
    "only",
    "onscreen",
    "onset",
    "onshore",
    "onslaught",
    "onstage",
    "onto",
    "onward",
    "onyx",
    "oops",
    "ooze",
    "oozy",
    "opacity",
    "opal",
    "open",
    "operable",
    "operate",
    "operating",
    "operation",
    "operative",
    "operator",
    "opium",
    "opossum",
    "opponent",
    "oppose",
    "opposing",
    "opposite",
    "oppressed",
    "oppressor",
    "opt",
    "opulently",
    "osmosis",
    "other",
    "otter",
    "ouch",
    "ought",
    "ounce",
    "outage",
    "outback",
    "outbid",
    "outboard",
    "outbound",
    "outbreak",
    "outburst",
    "outcast",
    "outclass",
    "outcome",
    "outdated",
    "outdoors",
    "outer",
    "outfield",
    "outfit",
    "outflank",
    "outgoing",
    "outgrow",
    "outhouse",
    "outing",
    "outlast",
    "outlet",
    "outline",
    "outlook",
    "outlying",
    "outmatch",
    "outmost",
    "outnumber",
    "outplayed",
    "outpost",
    "outpour",
    "output",
    "outrage",
    "outrank",
    "outreach",
    "outright",
    "outscore",
    "outsell",
    "outshine",
    "outshoot",
    "outsider",
    "outskirts",
    "outsmart",
    "outsource",
    "outspoken",
    "outtakes",
    "outthink",
    "outward",
    "outweigh",
    "outwit",
    "oval",
    "ovary",
    "oven",
    "overact",
    "overall",
    "overarch",
    "overbid",
    "overbill",
    "overbite",
    "overblown",
    "overboard",
    "overbook",
    "overbuilt",
    "overcast",
    "overcoat",
    "overcome",
    "overcook",
    "overcrowd",
    "overdraft",
    "overdrawn",
    "overdress",
    "overdrive",
    "overdue",
    "overeager",
    "overeater",
    "overexert",
    "overfed",
    "overfeed",
    "overfill",
    "overflow",
    "overfull",
    "overgrown",
    "overhand",
    "overhang",
    "overhaul",
    "overhead",
    "overhear",
    "overheat",
    "overhung",
    "overjoyed",
    "overkill",
    "overlabor",
    "overlaid",
    "overlap",
    "overlay",
    "overload",
    "overlook",
    "overlord",
    "overlying",
    "overnight",
    "overpass",
    "overpay",
    "overplant",
    "overplay",
    "overpower",
    "overprice",
    "overrate",
    "overreach",
    "overreact",
    "override",
    "overripe",
    "overrule",
    "overrun",
    "overshoot",
    "overshot",
    "oversight",
    "oversized",
    "oversleep",
    "oversold",
    "overspend",
    "overstate",
    "overstay",
    "overstep",
    "overstock",
    "overstuff",
    "oversweet",
    "overtake",
    "overthrow",
    "overtime",
    "overtly",
    "overtone",
    "overture",
    "overturn",
    "overuse",
    "overvalue",
    "overview",
    "overwrite",
    "owl",
    "oxford",
    "oxidant",
    "oxidation",
    "oxidize",
    "oxidizing",
    "oxygen",
    "oxymoron",
    "oyster",
    "ozone",
    "paced",
    "pacemaker",
    "pacific",
    "pacifier",
    "pacifism",
    "pacifist",
    "pacify",
    "padded",
    "padding",
    "paddle",
    "paddling",
    "padlock",
    "pagan",
    "pager",
    "paging",
    "pajamas",
    "palace",
    "palatable",
    "palm",
    "palpable",
    "palpitate",
    "paltry",
    "pampered",
    "pamperer",
    "pampers",
    "pamphlet",
    "panama",
    "pancake",
    "pancreas",
    "panda",
    "pandemic",
    "pang",
    "panhandle",
    "panic",
    "panning",
    "panorama",
    "panoramic",
    "panther",
    "pantomime",
    "pantry",
    "pants",
    "pantyhose",
    "paparazzi",
    "papaya",
    "paper",
    "paprika",
    "papyrus",
    "parabola",
    "parachute",
    "parade",
    "paradox",
    "paragraph",
    "parakeet",
    "paralegal",
    "paralyses",
    "paralysis",
    "paralyze",
    "paramedic",
    "parameter",
    "paramount",
    "parasail",
    "parasite",
    "parasitic",
    "parcel",
    "parched",
    "parchment",
    "pardon",
    "parish",
    "parka",
    "parking",
    "parkway",
    "parlor",
    "parmesan",
    "parole",
    "parrot",
    "parsley",
    "parsnip",
    "partake",
    "parted",
    "parting",
    "partition",
    "partly",
    "partner",
    "partridge",
    "party",
    "passable",
    "passably",
    "passage",
    "passcode",
    "passenger",
    "passerby",
    "passing",
    "passion",
    "passive",
    "passivism",
    "passover",
    "passport",
    "password",
    "pasta",
    "pasted",
    "pastel",
    "pastime",
    "pastor",
    "pastrami",
    "pasture",
    "pasty",
    "patchwork",
    "patchy",
    "paternal",
    "paternity",
    "path",
    "patience",
    "patient",
    "patio",
    "patriarch",
    "patriot",
    "patrol",
    "patronage",
    "patronize",
    "pauper",
    "pavement",
    "paver",
    "pavestone",
    "pavilion",
    "paving",
    "pawing",
    "payable",
    "payback",
    "paycheck",
    "payday",
    "payee",
    "payer",
    "paying",
    "payment",
    "payphone",
    "payroll",
    "pebble",
    "pebbly",
    "pecan",
    "pectin",
    "peculiar",
    "peddling",
    "pediatric",
    "pedicure",
    "pedigree",
    "pedometer",
    "pegboard",
    "pelican",
    "pellet",
    "pelt",
    "pelvis",
    "penalize",
    "penalty",
    "pencil",
    "pendant",
    "pending",
    "penholder",
    "penknife",
    "pennant",
    "penniless",
    "penny",
    "penpal",
    "pension",
    "pentagon",
    "pentagram",
    "pep",
    "perceive",
    "percent",
    "perch",
    "percolate",
    "perennial",
    "perfected",
    "perfectly",
    "perfume",
    "periscope",
    "perish",
    "perjurer",
    "perjury",
    "perkiness",
    "perky",
    "perm",
    "peroxide",
    "perpetual",
    "perplexed",
    "persecute",
    "persevere",
    "persuaded",
    "persuader",
    "pesky",
    "peso",
    "pessimism",
    "pessimist",
    "pester",
    "pesticide",
    "petal",
    "petite",
    "petition",
    "petri",
    "petroleum",
    "petted",
    "petticoat",
    "pettiness",
    "petty",
    "petunia",
    "phantom",
    "phobia",
    "phoenix",
    "phonebook",
    "phoney",
    "phonics",
    "phoniness",
    "phony",
    "phosphate",
    "photo",
    "phrase",
    "phrasing",
    "placard",
    "placate",
    "placidly",
    "plank",
    "planner",
    "plant",
    "plasma",
    "plaster",
    "plastic",
    "plated",
    "platform",
    "plating",
    "platinum",
    "platonic",
    "platter",
    "platypus",
    "plausible",
    "plausibly",
    "playable",
    "playback",
    "player",
    "playful",
    "playgroup",
    "playhouse",
    "playing",
    "playlist",
    "playmaker",
    "playmate",
    "playoff",
    "playpen",
    "playroom",
    "playset",
    "plaything",
    "playtime",
    "plaza",
    "pleading",
    "pleat",
    "pledge",
    "plentiful",
    "plenty",
    "plethora",
    "plexiglas",
    "pliable",
    "plod",
    "plop",
    "plot",
    "plow",
    "ploy",
    "pluck",
    "plug",
    "plunder",
    "plunging",
    "plural",
    "plus",
    "plutonium",
    "plywood",
    "poach",
    "pod",
    "poem",
    "poet",
    "pogo",
    "pointed",
    "pointer",
    "pointing",
    "pointless",
    "pointy",
    "poise",
    "poison",
    "poker",
    "poking",
    "polar",
    "police",
    "policy",
    "polio",
    "polish",
    "politely",
    "polka",
    "polo",
    "polyester",
    "polygon",
    "polygraph",
    "polymer",
    "poncho",
    "pond",
    "pony",
    "popcorn",
    "pope",
    "poplar",
    "popper",
    "poppy",
    "popsicle",
    "populace",
    "popular",
    "populate",
    "porcupine",
    "pork",
    "porous",
    "porridge",
    "portable",
    "portal",
    "portfolio",
    "porthole",
    "portion",
    "portly",
    "portside",
    "poser",
    "posh",
    "posing",
    "possible",
    "possibly",
    "possum",
    "postage",
    "postal",
    "postbox",
    "postcard",
    "posted",
    "poster",
    "posting",
    "postnasal",
    "posture",
    "postwar",
    "pouch",
    "pounce",
    "pouncing",
    "pound",
    "pouring",
    "pout",
    "powdered",
    "powdering",
    "powdery",
    "power",
    "powwow",
    "pox",
    "praising",
    "prance",
    "prancing",
    "pranker",
    "prankish",
    "prankster",
    "prayer",
    "praying",
    "preacher",
    "preaching",
    "preachy",
    "preamble",
    "precinct",
    "precise",
    "precision",
    "precook",
    "precut",
    "predator",
    "predefine",
    "predict",
    "preface",
    "prefix",
    "preflight",
    "preformed",
    "pregame",
    "pregnancy",
    "pregnant",
    "preheated",
    "prelaunch",
    "prelaw",
    "prelude",
    "premiere",
    "premises",
    "premium",
    "prenatal",
    "preoccupy",
    "preorder",
    "prepaid",
    "prepay",
    "preplan",
    "preppy",
    "preschool",
    "prescribe",
    "preseason",
    "preset",
    "preshow",
    "president",
    "presoak",
    "press",
    "presume",
    "presuming",
    "preteen",
    "pretended",
    "pretender",
    "pretense",
    "pretext",
    "pretty",
    "pretzel",
    "prevail",
    "prevalent",
    "prevent",
    "preview",
    "previous",
    "prewar",
    "prewashed",
    "prideful",
    "pried",
    "primal",
    "primarily",
    "primary",
    "primate",
    "primer",
    "primp",
    "princess",
    "print",
    "prior",
    "prism",
    "prison",
    "prissy",
    "pristine",
    "privacy",
    "private",
    "privatize",
    "prize",
    "proactive",
    "probable",
    "probably",
    "probation",
    "probe",
    "probing",
    "probiotic",
    "problem",
    "procedure",
    "process",
    "proclaim",
    "procreate",
    "procurer",
    "prodigal",
    "prodigy",
    "produce",
    "product",
    "profane",
    "profanity",
    "professed",
    "professor",
    "profile",
    "profound",
    "profusely",
    "progeny",
    "prognosis",
    "program",
    "progress",
    "projector",
    "prologue",
    "prolonged",
    "promenade",
    "prominent",
    "promoter",
    "promotion",
    "prompter",
    "promptly",
    "prone",
    "prong",
    "pronounce",
    "pronto",
    "proofing",
    "proofread",
    "proofs",
    "propeller",
    "properly",
    "property",
    "proponent",
    "proposal",
    "propose",
    "props",
    "prorate",
    "protector",
    "protegee",
    "proton",
    "prototype",
    "protozoan",
    "protract",
    "protrude",
    "proud",
    "provable",
    "proved",
    "proven",
    "provided",
    "provider",
    "providing",
    "province",
    "proving",
    "provoke",
    "provoking",
    "provolone",
    "prowess",
    "prowler",
    "prowling",
    "proximity",
    "proxy",
    "prozac",
    "prude",
    "prudishly",
    "prune",
    "pruning",
    "pry",
    "psychic",
    "public",
    "publisher",
    "pucker",
    "pueblo",
    "pug",
    "pull",
    "pulmonary",
    "pulp",
    "pulsate",
    "pulse",
    "pulverize",
    "puma",
    "pumice",
    "pummel",
    "punch",
    "punctual",
    "punctuate",
    "punctured",
    "pungent",
    "punisher",
    "punk",
    "pupil",
    "puppet",
    "puppy",
    "purchase",
    "pureblood",
    "purebred",
    "purely",
    "pureness",
    "purgatory",
    "purge",
    "purging",
    "purifier",
    "purify",
    "purist",
    "puritan",
    "purity",
    "purple",
    "purplish",
    "purposely",
    "purr",
    "purse",
    "pursuable",
    "pursuant",
    "pursuit",
    "purveyor",
    "pushcart",
    "pushchair",
    "pusher",
    "pushiness",
    "pushing",
    "pushover",
    "pushpin",
    "pushup",
    "pushy",
    "putdown",
    "putt",
    "puzzle",
    "puzzling",
    "pyramid",
    "pyromania",
    "python",
    "quack",
    "quadrant",
    "quail",
    "quaintly",
    "quake",
    "quaking",
    "qualified",
    "qualifier",
    "qualify",
    "quality",
    "qualm",
    "quantum",
    "quarrel",
    "quarry",
    "quartered",
    "quarterly",
    "quarters",
    "quartet",
    "quench",
    "query",
    "quicken",
    "quickly",
    "quickness",
    "quicksand",
    "quickstep",
    "quiet",
    "quill",
    "quilt",
    "quintet",
    "quintuple",
    "quirk",
    "quit",
    "quiver",
    "quizzical",
    "quotable",
    "quotation",
    "quote",
    "rabid",
    "race",
    "racing",
    "racism",
    "rack",
    "racoon",
    "radar",
    "radial",
    "radiance",
    "radiantly",
    "radiated",
    "radiation",
    "radiator",
    "radio",
    "radish",
    "raffle",
    "raft",
    "rage",
    "ragged",
    "raging",
    "ragweed",
    "raider",
    "railcar",
    "railing",
    "railroad",
    "railway",
    "raisin",
    "rake",
    "raking",
    "rally",
    "ramble",
    "rambling",
    "ramp",
    "ramrod",
    "ranch",
    "rancidity",
    "random",
    "ranged",
    "ranger",
    "ranging",
    "ranked",
    "ranking",
    "ransack",
    "ranting",
    "rants",
    "rare",
    "rarity",
    "rascal",
    "rash",
    "rasping",
    "ravage",
    "raven",
    "ravine",
    "raving",
    "ravioli",
    "ravishing",
    "reabsorb",
    "reach",
    "reacquire",
    "reaction",
    "reactive",
    "reactor",
    "reaffirm",
    "ream",
    "reanalyze",
    "reappear",
    "reapply",
    "reappoint",
    "reapprove",
    "rearrange",
    "rearview",
    "reason",
    "reassign",
    "reassure",
    "reattach",
    "reawake",
    "rebalance",
    "rebate",
    "rebel",
    "rebirth",
    "reboot",
    "reborn",
    "rebound",
    "rebuff",
    "rebuild",
    "rebuilt",
    "reburial",
    "rebuttal",
    "recall",
    "recant",
    "recapture",
    "recast",
    "recede",
    "recent",
    "recess",
    "recharger",
    "recipient",
    "recital",
    "recite",
    "reckless",
    "reclaim",
    "recliner",
    "reclining",
    "recluse",
    "reclusive",
    "recognize",
    "recoil",
    "recollect",
    "recolor",
    "reconcile",
    "reconfirm",
    "reconvene",
    "recopy",
    "record",
    "recount",
    "recoup",
    "recovery",
    "recreate",
    "rectal",
    "rectangle",
    "rectified",
    "rectify",
    "recycled",
    "recycler",
    "recycling",
    "reemerge",
    "reenact",
    "reenter",
    "reentry",
    "reexamine",
    "referable",
    "referee",
    "reference",
    "refill",
    "refinance",
    "refined",
    "refinery",
    "refining",
    "refinish",
    "reflected",
    "reflector",
    "reflex",
    "reflux",
    "refocus",
    "refold",
    "reforest",
    "reformat",
    "reformed",
    "reformer",
    "reformist",
    "refract",
    "refrain",
    "refreeze",
    "refresh",
    "refried",
    "refueling",
    "refund",
    "refurbish",
    "refurnish",
    "refusal",
    "refuse",
    "refusing",
    "refutable",
    "refute",
    "regain",
    "regalia",
    "regally",
    "reggae",
    "regime",
    "region",
    "register",
    "registrar",
    "registry",
    "regress",
    "regretful",
    "regroup",
    "regular",
    "regulate",
    "regulator",
    "rehab",
    "reheat",
    "rehire",
    "rehydrate",
    "reimburse",
    "reissue",
    "reiterate",
    "rejoice",
    "rejoicing",
    "rejoin",
    "rekindle",
    "relapse",
    "relapsing",
    "relatable",
    "related",
    "relation",
    "relative",
    "relax",
    "relay",
    "relearn",
    "release",
    "relenting",
    "reliable",
    "reliably",
    "reliance",
    "reliant",
    "relic",
    "relieve",
    "relieving",
    "relight",
    "relish",
    "relive",
    "reload",
    "relocate",
    "relock",
    "reluctant",
    "rely",
    "remake",
    "remark",
    "remarry",
    "rematch",
    "remedial",
    "remedy",
    "remember",
    "reminder",
    "remindful",
    "remission",
    "remix",
    "remnant",
    "remodeler",
    "remold",
    "remorse",
    "remote",
    "removable",
    "removal",
    "removed",
    "remover",
    "removing",
    "rename",
    "renderer",
    "rendering",
    "rendition",
    "renegade",
    "renewable",
    "renewably",
    "renewal",
    "renewed",
    "renounce",
    "renovate",
    "renovator",
    "rentable",
    "rental",
    "rented",
    "renter",
    "reoccupy",
    "reoccur",
    "reopen",
    "reorder",
    "repackage",
    "repacking",
    "repaint",
    "repair",
    "repave",
    "repaying",
    "repayment",
    "repeal",
    "repeated",
    "repeater",
    "repent",
    "rephrase",
    "replace",
    "replay",
    "replica",
    "reply",
    "reporter",
    "repose",
    "repossess",
    "repost",
    "repressed",
    "reprimand",
    "reprint",
    "reprise",
    "reproach",
    "reprocess",
    "reproduce",
    "reprogram",
    "reps",
    "reptile",
    "reptilian",
    "repugnant",
    "repulsion",
    "repulsive",
    "repurpose",
    "reputable",
    "reputably",
    "request",
    "require",
    "requisite",
    "reroute",
    "rerun",
    "resale",
    "resample",
    "rescuer",
    "reseal",
    "research",
    "reselect",
    "reseller",
    "resemble",
    "resend",
    "resent",
    "reset",
    "reshape",
    "reshoot",
    "reshuffle",
    "residence",
    "residency",
    "resident",
    "residual",
    "residue",
    "resigned",
    "resilient",
    "resistant",
    "resisting",
    "resize",
    "resolute",
    "resolved",
    "resonant",
    "resonate",
    "resort",
    "resource",
    "respect",
    "resubmit",
    "result",
    "resume",
    "resupply",
    "resurface",
    "resurrect",
    "retail",
    "retainer",
    "retaining",
    "retake",
    "retaliate",
    "retention",
    "rethink",
    "retinal",
    "retired",
    "retiree",
    "retiring",
    "retold",
    "retool",
    "retorted",
    "retouch",
    "retrace",
    "retract",
    "retrain",
    "retread",
    "retreat",
    "retrial",
    "retrieval",
    "retriever",
    "retry",
    "return",
    "retying",
    "retype",
    "reunion",
    "reunite",
    "reusable",
    "reuse",
    "reveal",
    "reveler",
    "revenge",
    "revenue",
    "reverb",
    "revered",
    "reverence",
    "reverend",
    "reversal",
    "reverse",
    "reversing",
    "reversion",
    "revert",
    "revisable",
    "revise",
    "revision",
    "revisit",
    "revivable",
    "revival",
    "reviver",
    "reviving",
    "revocable",
    "revoke",
    "revolt",
    "revolver",
    "revolving",
    "reward",
    "rewash",
    "rewind",
    "rewire",
    "reword",
    "rework",
    "rewrap",
    "rewrite",
    "rhyme",
    "ribbon",
    "ribcage",
    "rice",
    "riches",
    "richly",
    "richness",
    "rickety",
    "ricotta",
    "riddance",
    "ridden",
    "ride",
    "riding",
    "rifling",
    "rift",
    "rigging",
    "rigid",
    "rigor",
    "rimless",
    "rimmed",
    "rind",
    "rink",
    "rinse",
    "rinsing",
    "riot",
    "ripcord",
    "ripeness",
    "ripening",
    "ripping",
    "ripple",
    "rippling",
    "riptide",
    "rise",
    "rising",
    "risk",
    "risotto",
    "ritalin",
    "ritzy",
    "rival",
    "riverbank",
    "riverbed",
    "riverboat",
    "riverside",
    "riveter",
    "riveting",
    "roamer",
    "roaming",
    "roast",
    "robbing",
    "robe",
    "robin",
    "robotics",
    "robust",
    "rockband",
    "rocker",
    "rocket",
    "rockfish",
    "rockiness",
    "rocking",
    "rocklike",
    "rockslide",
    "rockstar",
    "rocky",
    "rogue",
    "roman",
    "romp",
    "rope",
    "roping",
    "roster",
    "rosy",
    "rotten",
    "rotting",
    "rotunda",
    "roulette",
    "rounding",
    "roundish",
    "roundness",
    "roundup",
    "roundworm",
    "routine",
    "routing",
    "rover",
    "roving",
    "royal",
    "rubbed",
    "rubber",
    "rubbing",
    "rubble",
    "rubdown",
    "ruby",
    "ruckus",
    "rudder",
    "rug",
    "ruined",
    "rule",
    "rumble",
    "rumbling",
    "rummage",
    "rumor",
    "runaround",
    "rundown",
    "runner",
    "running",
    "runny",
    "runt",
    "runway",
    "rupture",
    "rural",
    "ruse",
    "rush",
    "rust",
    "rut",
    "sabbath",
    "sabotage",
    "sacrament",
    "sacred",
    "sacrifice",
    "sadden",
    "saddlebag",
    "saddled",
    "saddling",
    "sadly",
    "sadness",
    "safari",
    "safeguard",
    "safehouse",
    "safely",
    "safeness",
    "saffron",
    "saga",
    "sage",
    "sagging",
    "saggy",
    "said",
    "saint",
    "sake",
    "salad",
    "salami",
    "salaried",
    "salary",
    "saline",
    "salon",
    "saloon",
    "salsa",
    "salt",
    "salutary",
    "salute",
    "salvage",
    "salvaging",
    "salvation",
    "same",
    "sample",
    "sampling",
    "sanction",
    "sanctity",
    "sanctuary",
    "sandal",
    "sandbag",
    "sandbank",
    "sandbar",
    "sandblast",
    "sandbox",
    "sanded",
    "sandfish",
    "sanding",
    "sandlot",
    "sandpaper",
    "sandpit",
    "sandstone",
    "sandstorm",
    "sandworm",
    "sandy",
    "sanitary",
    "sanitizer",
    "sank",
    "santa",
    "sapling",
    "sappiness",
    "sappy",
    "sarcasm",
    "sarcastic",
    "sardine",
    "sash",
    "sasquatch",
    "sassy",
    "satchel",
    "satiable",
    "satin",
    "satirical",
    "satisfied",
    "satisfy",
    "saturate",
    "saturday",
    "sauciness",
    "saucy",
    "sauna",
    "savage",
    "savanna",
    "saved",
    "savings",
    "savior",
    "savor",
    "saxophone",
    "say",
    "scabbed",
    "scabby",
    "scalded",
    "scalding",
    "scale",
    "scaling",
    "scallion",
    "scallop",
    "scalping",
    "scam",
    "scandal",
    "scanner",
    "scanning",
    "scant",
    "scapegoat",
    "scarce",
    "scarcity",
    "scarecrow",
    "scared",
    "scarf",
    "scarily",
    "scariness",
    "scarring",
    "scary",
    "scavenger",
    "scenic",
    "schedule",
    "schematic",
    "scheme",
    "scheming",
    "schilling",
    "schnapps",
    "scholar",
    "science",
    "scientist",
    "scion",
    "scoff",
    "scolding",
    "scone",
    "scoop",
    "scooter",
    "scope",
    "scorch",
    "scorebook",
    "scorecard",
    "scored",
    "scoreless",
    "scorer",
    "scoring",
    "scorn",
    "scorpion",
    "scotch",
    "scoundrel",
    "scoured",
    "scouring",
    "scouting",
    "scouts",
    "scowling",
    "scrabble",
    "scraggly",
    "scrambled",
    "scrambler",
    "scrap",
    "scratch",
    "scrawny",
    "screen",
    "scribble",
    "scribe",
    "scribing",
    "scrimmage",
    "script",
    "scroll",
    "scrooge",
    "scrounger",
    "scrubbed",
    "scrubber",
    "scruffy",
    "scrunch",
    "scrutiny",
    "scuba",
    "scuff",
    "sculptor",
    "sculpture",
    "scurvy",
    "scuttle",
    "secluded",
    "secluding",
    "seclusion",
    "second",
    "secrecy",
    "secret",
    "sectional",
    "sector",
    "secular",
    "securely",
    "security",
    "sedan",
    "sedate",
    "sedation",
    "sedative",
    "sediment",
    "seduce",
    "seducing",
    "segment",
    "seismic",
    "seizing",
    "seldom",
    "selected",
    "selection",
    "selective",
    "selector",
    "self",
    "seltzer",
    "semantic",
    "semester",
    "semicolon",
    "semifinal",
    "seminar",
    "semisoft",
    "semisweet",
    "senate",
    "senator",
    "send",
    "senior",
    "senorita",
    "sensation",
    "sensitive",
    "sensitize",
    "sensually",
    "sensuous",
    "sepia",
    "september",
    "septic",
    "septum",
    "sequel",
    "sequence",
    "sequester",
    "series",
    "sermon",
    "serotonin",
    "serpent",
    "serrated",
    "serve",
    "service",
    "serving",
    "sesame",
    "sessions",
    "setback",
    "setting",
    "settle",
    "settling",
    "setup",
    "sevenfold",
    "seventeen",
    "seventh",
    "seventy",
    "severity",
    "shabby",
    "shack",
    "shaded",
    "shadily",
    "shadiness",
    "shading",
    "shadow",
    "shady",
    "shaft",
    "shakable",
    "shakily",
    "shakiness",
    "shaking",
    "shaky",
    "shale",
    "shallot",
    "shallow",
    "shame",
    "shampoo",
    "shamrock",
    "shank",
    "shanty",
    "shape",
    "shaping",
    "share",
    "sharpener",
    "sharper",
    "sharpie",
    "sharply",
    "sharpness",
    "shawl",
    "sheath",
    "shed",
    "sheep",
    "sheet",
    "shelf",
    "shell",
    "shelter",
    "shelve",
    "shelving",
    "sherry",
    "shield",
    "shifter",
    "shifting",
    "shiftless",
    "shifty",
    "shimmer",
    "shimmy",
    "shindig",
    "shine",
    "shingle",
    "shininess",
    "shining",
    "shiny",
    "ship",
    "shirt",
    "shivering",
    "shock",
    "shone",
    "shoplift",
    "shopper",
    "shopping",
    "shoptalk",
    "shore",
    "shortage",
    "shortcake",
    "shortcut",
    "shorten",
    "shorter",
    "shorthand",
    "shortlist",
    "shortly",
    "shortness",
    "shorts",
    "shortwave",
    "shorty",
    "shout",
    "shove",
    "showbiz",
    "showcase",
    "showdown",
    "shower",
    "showgirl",
    "showing",
    "showman",
    "shown",
    "showoff",
    "showpiece",
    "showplace",
    "showroom",
    "showy",
    "shrank",
    "shrapnel",
    "shredder",
    "shredding",
    "shrewdly",
    "shriek",
    "shrill",
    "shrimp",
    "shrine",
    "shrink",
    "shrivel",
    "shrouded",
    "shrubbery",
    "shrubs",
    "shrug",
    "shrunk",
    "shucking",
    "shudder",
    "shuffle",
    "shuffling",
    "shun",
    "shush",
    "shut",
    "shy",
    "siamese",
    "siberian",
    "sibling",
    "siding",
    "sierra",
    "siesta",
    "sift",
    "sighing",
    "silenced",
    "silencer",
    "silent",
    "silica",
    "silicon",
    "silk",
    "silliness",
    "silly",
    "silo",
    "silt",
    "silver",
    "similarly",
    "simile",
    "simmering",
    "simple",
    "simplify",
    "simply",
    "sincere",
    "sincerity",
    "singer",
    "singing",
    "single",
    "singular",
    "sinister",
    "sinless",
    "sinner",
    "sinuous",
    "sip",
    "siren",
    "sister",
    "sitcom",
    "sitter",
    "sitting",
    "situated",
    "situation",
    "sixfold",
    "sixteen",
    "sixth",
    "sixties",
    "sixtieth",
    "sixtyfold",
    "sizable",
    "sizably",
    "size",
    "sizing",
    "sizzle",
    "sizzling",
    "skater",
    "skating",
    "skedaddle",
    "skeletal",
    "skeleton",
    "skeptic",
    "sketch",
    "skewed",
    "skewer",
    "skid",
    "skied",
    "skier",
    "skies",
    "skiing",
    "skilled",
    "skillet",
    "skillful",
    "skimmed",
    "skimmer",
    "skimming",
    "skimpily",
    "skincare",
    "skinhead",
    "skinless",
    "skinning",
    "skinny",
    "skintight",
    "skipper",
    "skipping",
    "skirmish",
    "skirt",
    "skittle",
    "skydiver",
    "skylight",
    "skyline",
    "skype",
    "skyrocket",
    "skyward",
    "slab",
    "slacked",
    "slacker",
    "slacking",
    "slackness",
    "slacks",
    "slain",
    "slam",
    "slander",
    "slang",
    "slapping",
    "slapstick",
    "slashed",
    "slashing",
    "slate",
    "slather",
    "slaw",
    "sled",
    "sleek",
    "sleep",
    "sleet",
    "sleeve",
    "slept",
    "sliceable",
    "sliced",
    "slicer",
    "slicing",
    "slick",
    "slider",
    "slideshow",
    "sliding",
    "slighted",
    "slighting",
    "slightly",
    "slimness",
    "slimy",
    "slinging",
    "slingshot",
    "slinky",
    "slip",
    "slit",
    "sliver",
    "slobbery",
    "slogan",
    "sloped",
    "sloping",
    "sloppily",
    "sloppy",
    "slot",
    "slouching",
    "slouchy",
    "sludge",
    "slug",
    "slum",
    "slurp",
    "slush",
    "sly",
    "small",
    "smartly",
    "smartness",
    "smasher",
    "smashing",
    "smashup",
    "smell",
    "smelting",
    "smile",
    "smilingly",
    "smirk",
    "smite",
    "smith",
    "smitten",
    "smock",
    "smog",
    "smoked",
    "smokeless",
    "smokiness",
    "smoking",
    "smoky",
    "smolder",
    "smooth",
    "smother",
    "smudge",
    "smudgy",
    "smuggler",
    "smuggling",
    "smugly",
    "smugness",
    "snack",
    "snagged",
    "snaking",
    "snap",
    "snare",
    "snarl",
    "snazzy",
    "sneak",
    "sneer",
    "sneeze",
    "sneezing",
    "snide",
    "sniff",
    "snippet",
    "snipping",
    "snitch",
    "snooper",
    "snooze",
    "snore",
    "snoring",
    "snorkel",
    "snort",
    "snout",
    "snowbird",
    "snowboard",
    "snowbound",
    "snowcap",
    "snowdrift",
    "snowdrop",
    "snowfall",
    "snowfield",
    "snowflake",
    "snowiness",
    "snowless",
    "snowman",
    "snowplow",
    "snowshoe",
    "snowstorm",
    "snowsuit",
    "snowy",
    "snub",
    "snuff",
    "snuggle",
    "snugly",
    "snugness",
    "speak",
    "spearfish",
    "spearhead",
    "spearman",
    "spearmint",
    "species",
    "specimen",
    "specked",
    "speckled",
    "specks",
    "spectacle",
    "spectator",
    "spectrum",
    "speculate",
    "speech",
    "speed",
    "spellbind",
    "speller",
    "spelling",
    "spendable",
    "spender",
    "spending",
    "spent",
    "spew",
    "sphere",
    "spherical",
    "sphinx",
    "spider",
    "spied",
    "spiffy",
    "spill",
    "spilt",
    "spinach",
    "spinal",
    "spindle",
    "spinner",
    "spinning",
    "spinout",
    "spinster",
    "spiny",
    "spiral",
    "spirited",
    "spiritism",
    "spirits",
    "spiritual",
    "splashed",
    "splashing",
    "splashy",
    "splatter",
    "spleen",
    "splendid",
    "splendor",
    "splice",
    "splicing",
    "splinter",
    "splotchy",
    "splurge",
    "spoilage",
    "spoiled",
    "spoiler",
    "spoiling",
    "spoils",
    "spoken",
    "spokesman",
    "sponge",
    "spongy",
    "sponsor",
    "spoof",
    "spookily",
    "spooky",
    "spool",
    "spoon",
    "spore",
    "sporting",
    "sports",
    "sporty",
    "spotless",
    "spotlight",
    "spotted",
    "spotter",
    "spotting",
    "spotty",
    "spousal",
    "spouse",
    "spout",
    "sprain",
    "sprang",
    "sprawl",
    "spray",
    "spree",
    "sprig",
    "spring",
    "sprinkled",
    "sprinkler",
    "sprint",
    "sprite",
    "sprout",
    "spruce",
    "sprung",
    "spry",
    "spud",
    "spur",
    "sputter",
    "spyglass",
    "squabble",
    "squad",
    "squall",
    "squander",
    "squash",
    "squatted",
    "squatter",
    "squatting",
    "squeak",
    "squealer",
    "squealing",
    "squeamish",
    "squeegee",
    "squeeze",
    "squeezing",
    "squid",
    "squiggle",
    "squiggly",
    "squint",
    "squire",
    "squirt",
    "squishier",
    "squishy",
    "stability",
    "stabilize",
    "stable",
    "stack",
    "stadium",
    "staff",
    "stage",
    "staging",
    "stagnant",
    "stagnate",
    "stainable",
    "stained",
    "staining",
    "stainless",
    "stalemate",
    "staleness",
    "stalling",
    "stallion",
    "stamina",
    "stammer",
    "stamp",
    "stand",
    "stank",
    "staple",
    "stapling",
    "starboard",
    "starch",
    "stardom",
    "stardust",
    "starfish",
    "stargazer",
    "staring",
    "stark",
    "starless",
    "starlet",
    "starlight",
    "starlit",
    "starring",
    "starry",
    "starship",
    "starter",
    "starting",
    "startle",
    "startling",
    "startup",
    "starved",
    "starving",
    "stash",
    "state",
    "static",
    "statistic",
    "statue",
    "stature",
    "status",
    "statute",
    "statutory",
    "staunch",
    "stays",
    "steadfast",
    "steadier",
    "steadily",
    "steadying",
    "steam",
    "steed",
    "steep",
    "steerable",
    "steering",
    "steersman",
    "stegosaur",
    "stellar",
    "stem",
    "stench",
    "stencil",
    "step",
    "stereo",
    "sterile",
    "sterility",
    "sterilize",
    "sterling",
    "sternness",
    "sternum",
    "stew",
    "stick",
    "stiffen",
    "stiffly",
    "stiffness",
    "stifle",
    "stifling",
    "stillness",
    "stilt",
    "stimulant",
    "stimulate",
    "stimuli",
    "stimulus",
    "stinger",
    "stingily",
    "stinging",
    "stingray",
    "stingy",
    "stinking",
    "stinky",
    "stipend",
    "stipulate",
    "stir",
    "stitch",
    "stock",
    "stoic",
    "stoke",
    "stole",
    "stomp",
    "stonewall",
    "stoneware",
    "stonework",
    "stoning",
    "stony",
    "stood",
    "stooge",
    "stool",
    "stoop",
    "stoplight",
    "stoppable",
    "stoppage",
    "stopped",
    "stopper",
    "stopping",
    "stopwatch",
    "storable",
    "storage",
    "storeroom",
    "storewide",
    "storm",
    "stout",
    "stove",
    "stowaway",
    "stowing",
    "straddle",
    "straggler",
    "strained",
    "strainer",
    "straining",
    "strangely",
    "stranger",
    "strangle",
    "strategic",
    "strategy",
    "stratus",
    "straw",
    "stray",
    "streak",
    "stream",
    "street",
    "strength",
    "strenuous",
    "strep",
    "stress",
    "stretch",
    "strewn",
    "stricken",
    "strict",
    "stride",
    "strife",
    "strike",
    "striking",
    "strive",
    "striving",
    "strobe",
    "strode",
    "stroller",
    "strongbox",
    "strongly",
    "strongman",
    "struck",
    "structure",
    "strudel",
    "struggle",
    "strum",
    "strung",
    "strut",
    "stubbed",
    "stubble",
    "stubbly",
    "stubborn",
    "stucco",
    "stuck",
    "student",
    "studied",
    "studio",
    "study",
    "stuffed",
    "stuffing",
    "stuffy",
    "stumble",
    "stumbling",
    "stump",
    "stung",
    "stunned",
    "stunner",
    "stunning",
    "stunt",
    "stupor",
    "sturdily",
    "sturdy",
    "styling",
    "stylishly",
    "stylist",
    "stylized",
    "stylus",
    "suave",
    "subarctic",
    "subatomic",
    "subdivide",
    "subdued",
    "subduing",
    "subfloor",
    "subgroup",
    "subheader",
    "subject",
    "sublease",
    "sublet",
    "sublevel",
    "sublime",
    "submarine",
    "submerge",
    "submersed",
    "submitter",
    "subpanel",
    "subpar",
    "subplot",
    "subprime",
    "subscribe",
    "subscript",
    "subsector",
    "subside",
    "subsiding",
    "subsidize",
    "subsidy",
    "subsoil",
    "subsonic",
    "substance",
    "subsystem",
    "subtext",
    "subtitle",
    "subtly",
    "subtotal",
    "subtract",
    "subtype",
    "suburb",
    "subway",
    "subwoofer",
    "subzero",
    "succulent",
    "such",
    "suction",
    "sudden",
    "sudoku",
    "suds",
    "sufferer",
    "suffering",
    "suffice",
    "suffix",
    "suffocate",
    "suffrage",
    "sugar",
    "suggest",
    "suing",
    "suitable",
    "suitably",
    "suitcase",
    "suitor",
    "sulfate",
    "sulfide",
    "sulfite",
    "sulfur",
    "sulk",
    "sullen",
    "sulphate",
    "sulphuric",
    "sultry",
    "superbowl",
    "superglue",
    "superhero",
    "superior",
    "superjet",
    "superman",
    "supermom",
    "supernova",
    "supervise",
    "supper",
    "supplier",
    "supply",
    "support",
    "supremacy",
    "supreme",
    "surcharge",
    "surely",
    "sureness",
    "surface",
    "surfacing",
    "surfboard",
    "surfer",
    "surgery",
    "surgical",
    "surging",
    "surname",
    "surpass",
    "surplus",
    "surprise",
    "surreal",
    "surrender",
    "surrogate",
    "surround",
    "survey",
    "survival",
    "survive",
    "surviving",
    "survivor",
    "sushi",
    "suspect",
    "suspend",
    "suspense",
    "sustained",
    "sustainer",
    "swab",
    "swaddling",
    "swagger",
    "swampland",
    "swan",
    "swapping",
    "swarm",
    "sway",
    "swear",
    "sweat",
    "sweep",
    "swell",
    "swept",
    "swerve",
    "swifter",
    "swiftly",
    "swiftness",
    "swimmable",
    "swimmer",
    "swimming",
    "swimsuit",
    "swimwear",
    "swinger",
    "swinging",
    "swipe",
    "swirl",
    "switch",
    "swivel",
    "swizzle",
    "swooned",
    "swoop",
    "swoosh",
    "swore",
    "sworn",
    "swung",
    "sycamore",
    "sympathy",
    "symphonic",
    "symphony",
    "symptom",
    "synapse",
    "syndrome",
    "synergy",
    "synopses",
    "synopsis",
    "synthesis",
    "synthetic",
    "syrup",
    "system",
    "t-shirt",
    "tabasco",
    "tabby",
    "tableful",
    "tables",
    "tablet",
    "tableware",
    "tabloid",
    "tackiness",
    "tacking",
    "tackle",
    "tackling",
    "tacky",
    "taco",
    "tactful",
    "tactical",
    "tactics",
    "tactile",
    "tactless",
    "tadpole",
    "taekwondo",
    "tag",
    "tainted",
    "take",
    "taking",
    "talcum",
    "talisman",
    "tall",
    "talon",
    "tamale",
    "tameness",
    "tamer",
    "tamper",
    "tank",
    "tanned",
    "tannery",
    "tanning",
    "tantrum",
    "tapeless",
    "tapered",
    "tapering",
    "tapestry",
    "tapioca",
    "tapping",
    "taps",
    "tarantula",
    "target",
    "tarmac",
    "tarnish",
    "tarot",
    "tartar",
    "tartly",
    "tartness",
    "task",
    "tassel",
    "taste",
    "tastiness",
    "tasting",
    "tasty",
    "tattered",
    "tattle",
    "tattling",
    "tattoo",
    "taunt",
    "tavern",
    "thank",
    "that",
    "thaw",
    "theater",
    "theatrics",
    "thee",
    "theft",
    "theme",
    "theology",
    "theorize",
    "thermal",
    "thermos",
    "thesaurus",
    "these",
    "thesis",
    "thespian",
    "thicken",
    "thicket",
    "thickness",
    "thieving",
    "thievish",
    "thigh",
    "thimble",
    "thing",
    "think",
    "thinly",
    "thinner",
    "thinness",
    "thinning",
    "thirstily",
    "thirsting",
    "thirsty",
    "thirteen",
    "thirty",
    "thong",
    "thorn",
    "those",
    "thousand",
    "thrash",
    "thread",
    "threaten",
    "threefold",
    "thrift",
    "thrill",
    "thrive",
    "thriving",
    "throat",
    "throbbing",
    "throng",
    "throttle",
    "throwaway",
    "throwback",
    "thrower",
    "throwing",
    "thud",
    "thumb",
    "thumping",
    "thursday",
    "thus",
    "thwarting",
    "thyself",
    "tiara",
    "tibia",
    "tidal",
    "tidbit",
    "tidiness",
    "tidings",
    "tidy",
    "tiger",
    "tighten",
    "tightly",
    "tightness",
    "tightrope",
    "tightwad",
    "tigress",
    "tile",
    "tiling",
    "till",
    "tilt",
    "timid",
    "timing",
    "timothy",
    "tinderbox",
    "tinfoil",
    "tingle",
    "tingling",
    "tingly",
    "tinker",
    "tinkling",
    "tinsel",
    "tinsmith",
    "tint",
    "tinwork",
    "tiny",
    "tipoff",
    "tipped",
    "tipper",
    "tipping",
    "tiptoeing",
    "tiptop",
    "tiring",
    "tissue",
    "trace",
    "tracing",
    "track",
    "traction",
    "tractor",
    "trade",
    "trading",
    "tradition",
    "traffic",
    "tragedy",
    "trailing",
    "trailside",
    "train",
    "traitor",
    "trance",
    "tranquil",
    "transfer",
    "transform",
    "translate",
    "transpire",
    "transport",
    "transpose",
    "trapdoor",
    "trapeze",
    "trapezoid",
    "trapped",
    "trapper",
    "trapping",
    "traps",
    "trash",
    "travel",
    "traverse",
    "travesty",
    "tray",
    "treachery",
    "treading",
    "treadmill",
    "treason",
    "treat",
    "treble",
    "tree",
    "trekker",
    "tremble",
    "trembling",
    "tremor",
    "trench",
    "trend",
    "trespass",
    "triage",
    "trial",
    "triangle",
    "tribesman",
    "tribunal",
    "tribune",
    "tributary",
    "tribute",
    "triceps",
    "trickery",
    "trickily",
    "tricking",
    "trickle",
    "trickster",
    "tricky",
    "tricolor",
    "tricycle",
    "trident",
    "tried",
    "trifle",
    "trifocals",
    "trillion",
    "trilogy",
    "trimester",
    "trimmer",
    "trimming",
    "trimness",
    "trinity",
    "trio",
    "tripod",
    "tripping",
    "triumph",
    "trivial",
    "trodden",
    "trolling",
    "trombone",
    "trophy",
    "tropical",
    "tropics",
    "trouble",
    "troubling",
    "trough",
    "trousers",
    "trout",
    "trowel",
    "truce",
    "truck",
    "truffle",
    "trump",
    "trunks",
    "trustable",
    "trustee",
    "trustful",
    "trusting",
    "trustless",
    "truth",
    "try",
    "tubby",
    "tubeless",
    "tubular",
    "tucking",
    "tuesday",
    "tug",
    "tuition",
    "tulip",
    "tumble",
    "tumbling",
    "tummy",
    "turban",
    "turbine",
    "turbofan",
    "turbojet",
    "turbulent",
    "turf",
    "turkey",
    "turmoil",
    "turret",
    "turtle",
    "tusk",
    "tutor",
    "tutu",
    "tux",
    "tweak",
    "tweed",
    "tweet",
    "tweezers",
    "twelve",
    "twentieth",
    "twenty",
    "twerp",
    "twice",
    "twiddle",
    "twiddling",
    "twig",
    "twilight",
    "twine",
    "twins",
    "twirl",
    "twistable",
    "twisted",
    "twister",
    "twisting",
    "twisty",
    "twitch",
    "twitter",
    "tycoon",
    "tying",
    "tyke",
    "udder",
    "ultimate",
    "ultimatum",
    "ultra",
    "umbilical",
    "umbrella",
    "umpire",
    "unabashed",
    "unable",
    "unadorned",
    "unadvised",
    "unafraid",
    "unaired",
    "unaligned",
    "unaltered",
    "unarmored",
    "unashamed",
    "unaudited",
    "unawake",
    "unaware",
    "unbaked",
    "unbalance",
    "unbeaten",
    "unbend",
    "unbent",
    "unbiased",
    "unbitten",
    "unblended",
    "unblessed",
    "unblock",
    "unbolted",
    "unbounded",
    "unboxed",
    "unbraided",
    "unbridle",
    "unbroken",
    "unbuckled",
    "unbundle",
    "unburned",
    "unbutton",
    "uncanny",
    "uncapped",
    "uncaring",
    "uncertain",
    "unchain",
    "unchanged",
    "uncharted",
    "uncheck",
    "uncivil",
    "unclad",
    "unclaimed",
    "unclamped",
    "unclasp",
    "uncle",
    "unclip",
    "uncloak",
    "unclog",
    "unclothed",
    "uncoated",
    "uncoiled",
    "uncolored",
    "uncombed",
    "uncommon",
    "uncooked",
    "uncork",
    "uncorrupt",
    "uncounted",
    "uncouple",
    "uncouth",
    "uncover",
    "uncross",
    "uncrown",
    "uncrushed",
    "uncured",
    "uncurious",
    "uncurled",
    "uncut",
    "undamaged",
    "undated",
    "undaunted",
    "undead",
    "undecided",
    "undefined",
    "underage",
    "underarm",
    "undercoat",
    "undercook",
    "undercut",
    "underdog",
    "underdone",
    "underfed",
    "underfeed",
    "underfoot",
    "undergo",
    "undergrad",
    "underhand",
    "underline",
    "underling",
    "undermine",
    "undermost",
    "underpaid",
    "underpass",
    "underpay",
    "underrate",
    "undertake",
    "undertone",
    "undertook",
    "undertow",
    "underuse",
    "underwear",
    "underwent",
    "underwire",
    "undesired",
    "undiluted",
    "undivided",
    "undocked",
    "undoing",
    "undone",
    "undrafted",
    "undress",
    "undrilled",
    "undusted",
    "undying",
    "unearned",
    "unearth",
    "unease",
    "uneasily",
    "uneasy",
    "uneatable",
    "uneaten",
    "unedited",
    "unelected",
    "unending",
    "unengaged",
    "unenvied",
    "unequal",
    "unethical",
    "uneven",
    "unexpired",
    "unexposed",
    "unfailing",
    "unfair",
    "unfasten",
    "unfazed",
    "unfeeling",
    "unfiled",
    "unfilled",
    "unfitted",
    "unfitting",
    "unfixable",
    "unfixed",
    "unflawed",
    "unfocused",
    "unfold",
    "unfounded",
    "unframed",
    "unfreeze",
    "unfrosted",
    "unfrozen",
    "unfunded",
    "unglazed",
    "ungloved",
    "unglue",
    "ungodly",
    "ungraded",
    "ungreased",
    "unguarded",
    "unguided",
    "unhappily",
    "unhappy",
    "unharmed",
    "unhealthy",
    "unheard",
    "unhearing",
    "unheated",
    "unhelpful",
    "unhidden",
    "unhinge",
    "unhitched",
    "unholy",
    "unhook",
    "unicorn",
    "unicycle",
    "unified",
    "unifier",
    "uniformed",
    "uniformly",
    "unify",
    "unimpeded",
    "uninjured",
    "uninstall",
    "uninsured",
    "uninvited",
    "union",
    "uniquely",
    "unisexual",
    "unison",
    "unissued",
    "unit",
    "universal",
    "universe",
    "unjustly",
    "unkempt",
    "unkind",
    "unknotted",
    "unknowing",
    "unknown",
    "unlaced",
    "unlatch",
    "unlawful",
    "unleaded",
    "unlearned",
    "unleash",
    "unless",
    "unleveled",
    "unlighted",
    "unlikable",
    "unlimited",
    "unlined",
    "unlinked",
    "unlisted",
    "unlit",
    "unlivable",
    "unloaded",
    "unloader",
    "unlocked",
    "unlocking",
    "unlovable",
    "unloved",
    "unlovely",
    "unloving",
    "unluckily",
    "unlucky",
    "unmade",
    "unmanaged",
    "unmanned",
    "unmapped",
    "unmarked",
    "unmasked",
    "unmasking",
    "unmatched",
    "unmindful",
    "unmixable",
    "unmixed",
    "unmolded",
    "unmoral",
    "unmovable",
    "unmoved",
    "unmoving",
    "unnamable",
    "unnamed",
    "unnatural",
    "unneeded",
    "unnerve",
    "unnerving",
    "unnoticed",
    "unopened",
    "unopposed",
    "unpack",
    "unpadded",
    "unpaid",
    "unpainted",
    "unpaired",
    "unpaved",
    "unpeeled",
    "unpicked",
    "unpiloted",
    "unpinned",
    "unplanned",
    "unplanted",
    "unpleased",
    "unpledged",
    "unplowed",
    "unplug",
    "unpopular",
    "unproven",
    "unquote",
    "unranked",
    "unrated",
    "unraveled",
    "unreached",
    "unread",
    "unreal",
    "unreeling",
    "unrefined",
    "unrelated",
    "unrented",
    "unrest",
    "unretired",
    "unrevised",
    "unrigged",
    "unripe",
    "unrivaled",
    "unroasted",
    "unrobed",
    "unroll",
    "unruffled",
    "unruly",
    "unrushed",
    "unsaddle",
    "unsafe",
    "unsaid",
    "unsalted",
    "unsaved",
    "unsavory",
    "unscathed",
    "unscented",
    "unscrew",
    "unsealed",
    "unseated",
    "unsecured",
    "unseeing",
    "unseemly",
    "unseen",
    "unselect",
    "unselfish",
    "unsent",
    "unsettled",
    "unshackle",
    "unshaken",
    "unshaved",
    "unshaven",
    "unsheathe",
    "unshipped",
    "unsightly",
    "unsigned",
    "unskilled",
    "unsliced",
    "unsmooth",
    "unsnap",
    "unsocial",
    "unsoiled",
    "unsold",
    "unsolved",
    "unsorted",
    "unspoiled",
    "unspoken",
    "unstable",
    "unstaffed",
    "unstamped",
    "unsteady",
    "unsterile",
    "unstirred",
    "unstitch",
    "unstopped",
    "unstuck",
    "unstuffed",
    "unstylish",
    "unsubtle",
    "unsubtly",
    "unsuited",
    "unsure",
    "unsworn",
    "untagged",
    "untainted",
    "untaken",
    "untamed",
    "untangled",
    "untapped",
    "untaxed",
    "unthawed",
    "unthread",
    "untidy",
    "untie",
    "until",
    "untimed",
    "untimely",
    "untitled",
    "untoasted",
    "untold",
    "untouched",
    "untracked",
    "untrained",
    "untreated",
    "untried",
    "untrimmed",
    "untrue",
    "untruth",
    "unturned",
    "untwist",
    "untying",
    "unusable",
    "unused",
    "unusual",
    "unvalued",
    "unvaried",
    "unvarying",
    "unveiled",
    "unveiling",
    "unvented",
    "unviable",
    "unvisited",
    "unvocal",
    "unwanted",
    "unwarlike",
    "unwary",
    "unwashed",
    "unwatched",
    "unweave",
    "unwed",
    "unwelcome",
    "unwell",
    "unwieldy",
    "unwilling",
    "unwind",
    "unwired",
    "unwitting",
    "unwomanly",
    "unworldly",
    "unworn",
    "unworried",
    "unworthy",
    "unwound",
    "unwoven",
    "unwrapped",
    "unwritten",
    "unzip",
    "upbeat",
    "upchuck",
    "upcoming",
    "upcountry",
    "update",
    "upfront",
    "upgrade",
    "upheaval",
    "upheld",
    "uphill",
    "uphold",
    "uplifted",
    "uplifting",
    "upload",
    "upon",
    "upper",
    "upright",
    "uprising",
    "upriver",
    "uproar",
    "uproot",
    "upscale",
    "upside",
    "upstage",
    "upstairs",
    "upstart",
    "upstate",
    "upstream",
    "upstroke",
    "upswing",
    "uptake",
    "uptight",
    "uptown",
    "upturned",
    "upward",
    "upwind",
    "uranium",
    "urban",
    "urchin",
    "urethane",
    "urgency",
    "urgent",
    "urging",
    "urologist",
    "urology",
    "usable",
    "usage",
    "useable",
    "used",
    "uselessly",
    "user",
    "usher",
    "usual",
    "utensil",
    "utility",
    "utilize",
    "utmost",
    "utopia",
    "utter",
    "vacancy",
    "vacant",
    "vacate",
    "vacation",
    "vagabond",
    "vagrancy",
    "vagrantly",
    "vaguely",
    "vagueness",
    "valiant",
    "valid",
    "valium",
    "valley",
    "valuables",
    "value",
    "vanilla",
    "vanish",
    "vanity",
    "vanquish",
    "vantage",
    "vaporizer",
    "variable",
    "variably",
    "varied",
    "variety",
    "various",
    "varmint",
    "varnish",
    "varsity",
    "varying",
    "vascular",
    "vaseline",
    "vastly",
    "vastness",
    "veal",
    "vegan",
    "veggie",
    "vehicular",
    "velcro",
    "velocity",
    "velvet",
    "vendetta",
    "vending",
    "vendor",
    "veneering",
    "vengeful",
    "venomous",
    "ventricle",
    "venture",
    "venue",
    "venus",
    "verbalize",
    "verbally",
    "verbose",
    "verdict",
    "verify",
    "verse",
    "version",
    "versus",
    "vertebrae",
    "vertical",
    "vertigo",
    "very",
    "vessel",
    "vest",
    "veteran",
    "veto",
    "vexingly",
    "viability",
    "viable",
    "vibes",
    "vice",
    "vicinity",
    "victory",
    "video",
    "viewable",
    "viewer",
    "viewing",
    "viewless",
    "viewpoint",
    "vigorous",
    "village",
    "villain",
    "vindicate",
    "vineyard",
    "vintage",
    "violate",
    "violation",
    "violator",
    "violet",
    "violin",
    "viper",
    "viral",
    "virtual",
    "virtuous",
    "virus",
    "visa",
    "viscosity",
    "viscous",
    "viselike",
    "visible",
    "visibly",
    "vision",
    "visiting",
    "visitor",
    "visor",
    "vista",
    "vitality",
    "vitalize",
    "vitally",
    "vitamins",
    "vivacious",
    "vividly",
    "vividness",
    "vixen",
    "vocalist",
    "vocalize",
    "vocally",
    "vocation",
    "voice",
    "voicing",
    "void",
    "volatile",
    "volley",
    "voltage",
    "volumes",
    "voter",
    "voting",
    "voucher",
    "vowed",
    "vowel",
    "voyage",
    "wackiness",
    "wad",
    "wafer",
    "waffle",
    "waged",
    "wager",
    "wages",
    "waggle",
    "wagon",
    "wake",
    "waking",
    "walk",
    "walmart",
    "walnut",
    "walrus",
    "waltz",
    "wand",
    "wannabe",
    "wanted",
    "wanting",
    "wasabi",
    "washable",
    "washbasin",
    "washboard",
    "washbowl",
    "washcloth",
    "washday",
    "washed",
    "washer",
    "washhouse",
    "washing",
    "washout",
    "washroom",
    "washstand",
    "washtub",
    "wasp",
    "wasting",
    "watch",
    "water",
    "waviness",
    "waving",
    "wavy",
    "whacking",
    "whacky",
    "wham",
    "wharf",
    "wheat",
    "whenever",
    "whiff",
    "whimsical",
    "whinny",
    "whiny",
    "whisking",
    "whoever",
    "whole",
    "whomever",
    "whoopee",
    "whooping",
    "whoops",
    "why",
    "wick",
    "widely",
    "widen",
    "widget",
    "widow",
    "width",
    "wieldable",
    "wielder",
    "wife",
    "wifi",
    "wikipedia",
    "wildcard",
    "wildcat",
    "wilder",
    "wildfire",
    "wildfowl",
    "wildland",
    "wildlife",
    "wildly",
    "wildness",
    "willed",
    "willfully",
    "willing",
    "willow",
    "willpower",
    "wilt",
    "wimp",
    "wince",
    "wincing",
    "wind",
    "wing",
    "winking",
    "winner",
    "winnings",
    "winter",
    "wipe",
    "wired",
    "wireless",
    "wiring",
    "wiry",
    "wisdom",
    "wise",
    "wish",
    "wisplike",
    "wispy",
    "wistful",
    "wizard",
    "wobble",
    "wobbling",
    "wobbly",
    "wok",
    "wolf",
    "wolverine",
    "womanhood",
    "womankind",
    "womanless",
    "womanlike",
    "womanly",
    "womb",
    "woof",
    "wooing",
    "wool",
    "woozy",
    "word",
    "work",
    "worried",
    "worrier",
    "worrisome",
    "worry",
    "worsening",
    "worshiper",
    "worst",
    "wound",
    "woven",
    "wow",
    "wrangle",
    "wrath",
    "wreath",
    "wreckage",
    "wrecker",
    "wrecking",
    "wrench",
    "wriggle",
    "wriggly",
    "wrinkle",
    "wrinkly",
    "wrist",
    "writing",
    "written",
    "wrongdoer",
    "wronged",
    "wrongful",
    "wrongly",
    "wrongness",
    "wrought",
    "xbox",
    "xerox",
    "yahoo",
    "yam",
    "yanking",
    "yapping",
    "yard",
    "yarn",
    "yeah",
    "yearbook",
    "yearling",
    "yearly",
    "yearning",
    "yeast",
    "yelling",
    "yelp",
    "yen",
    "yesterday",
    "yiddish",
    "yield",
    "yin",
    "yippee",
    "yo-yo",
    "yodel",
    "yoga",
    "yogurt",
    "yonder",
    "yoyo",
    "yummy",
    "zap",
    "zealous",
    "zebra",
    "zen",
    "zeppelin",
    "zero",
    "zestfully",
    "zesty",
    "zigzagged",
    "zipfile",
    "zipping",
    "zippy",
    "zips",
    "zit",
    "zodiac",
    "zombie",
    "zone",
    "zoning",
    "zookeeper",
    "zoologist",
    "zoology",
    "zoom",
];

;// ../../libs/common/src/platform/services/key-state/org-keys.state.ts

const org_keys_state_USER_ENCRYPTED_ORGANIZATION_KEYS = UserKeyDefinition.record(CRYPTO_DISK, "organizationKeys", {
    deserializer: (obj) => obj,
    clearOn: ["logout"],
});

;// ../../libs/common/src/platform/services/key-state/provider-keys.state.ts

const provider_keys_state_USER_ENCRYPTED_PROVIDER_KEYS = UserKeyDefinition.record(CRYPTO_DISK, "providerKeys", {
    deserializer: (obj) => obj,
    clearOn: ["logout"],
});

;// ../../libs/common/src/platform/services/key-state/user-key.state.ts


/**
 * Ever had user key is a hack that allows differentiating TDE users that
 * have logged and unlocked in at least once fully, from ones that have not.
 * Depending on this, routing happens to the login-initiated or lock component.
 * The former allows trusting the device, and has master password (if available)
 * or trusted-device / admin approval as unlock methods. The latter has regular
 * lock methods.
 *
 * Ideally, this state hack would be replaced by a more robust solution that just
 * checks the available unlock methods, and routes depending on those.
 */
const user_key_state_USER_EVER_HAD_USER_KEY = new UserKeyDefinition(CRYPTO_DISK, "everHadUserKey", {
    deserializer: (obj) => obj,
    clearOn: ["logout"],
});
const USER_KEY = UserKeyDefinition.record(CRYPTO_MEMORY, "userKey", {
    deserializer: (obj) => SymmetricCryptoKey.fromJSON(obj),
    clearOn: ["logout", "lock"],
    // Prevents the state from caching and rxjs observable becoming hot observable.
    cleanupDelayMs: 0,
});

;// ../../libs/key-management/src/key.service.ts
var key_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};















const USER_KEY_STATE_KEY = "";
class DefaultKeyService {
    constructor(masterPasswordService, keyGenerationService, cryptoFunctionService, encryptService, platformUtilService, logService, stateService, accountService, stateProvider, kdfConfigService, accountCryptographyStateService) {
        this.masterPasswordService = masterPasswordService;
        this.keyGenerationService = keyGenerationService;
        this.cryptoFunctionService = cryptoFunctionService;
        this.encryptService = encryptService;
        this.platformUtilService = platformUtilService;
        this.logService = logService;
        this.stateService = stateService;
        this.accountService = accountService;
        this.stateProvider = stateProvider;
        this.kdfConfigService = kdfConfigService;
        this.accountCryptographyStateService = accountCryptographyStateService;
        this.activeUserOrgKeys$ = this.stateProvider.activeUserId$.pipe((0,external_rxjs_namespaceObject.switchMap)((userId) => (userId != null ? this.orgKeys$(userId) : external_rxjs_namespaceObject.NEVER)), (0,external_rxjs_namespaceObject.filter)((orgKeys) => orgKeys != null), (0,external_rxjs_namespaceObject.distinctUntilChanged)(), (0,external_rxjs_namespaceObject.shareReplay)({ bufferSize: 1, refCount: false }));
    }
    setUserKey(key, userId) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            if (key == null) {
                throw new Error("No key provided. Lock the user to clear the key");
            }
            if (userId == null) {
                throw new Error("No userId provided.");
            }
            // Set userId to ensure we have one for the account status update
            yield this.stateProvider.setUserState(USER_KEY, this.userKeyToStateObject(key), userId);
            yield this.stateProvider.setUserState(user_key_state_USER_EVER_HAD_USER_KEY, true, userId);
            yield this.storeAdditionalKeys(key, userId);
            // Await the key actually being set. This ensures that any subsequent callers know the key is already in state.
            // There were bugs related to the stateprovider observables in the past that caused issues around this.
            const userKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.userKey$(userId).pipe((0,external_rxjs_namespaceObject.filter)((k) => k != null)));
            if (userKey == null) {
                throw new Error("Failed to set user key");
            }
        });
    }
    refreshAdditionalKeys(userId) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            if (userId == null) {
                throw new Error("UserId is required.");
            }
            const key = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.userKey$(userId));
            if (key == null) {
                throw new Error("No user key found for: " + userId);
            }
            yield this.setUserKey(key, userId);
        });
    }
    everHadUserKey$(userId) {
        return this.stateProvider
            .getUser(userId, user_key_state_USER_EVER_HAD_USER_KEY)
            .state$.pipe((0,external_rxjs_namespaceObject.map)((x) => x !== null && x !== void 0 ? x : false));
    }
    getInMemoryUserKeyFor$(userId) {
        return this.stateProvider
            .getUserState$(USER_KEY, userId)
            .pipe((0,external_rxjs_namespaceObject.map)((userKey) => this.stateObjectToUserKey(userKey)));
    }
    /**
     * @deprecated Use {@link userKey$} with a required {@link UserId} instead.
     */
    getUserKey(userId) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            const userKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.stateProvider.getUserState$(USER_KEY, userId));
            return this.stateObjectToUserKey(userKey);
        });
    }
    getUserKeyFromStorage(keySuffix, userId) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            if (userId == null) {
                throw new Error("UserId is required");
            }
            const userKey = yield this.getKeyFromStorage(keySuffix, userId);
            if (userKey == null) {
                return null;
            }
            if (!(yield this.validateUserKey(userKey, userId))) {
                this.logService.warning("Invalid key, throwing away stored keys");
                yield this.clearAllStoredUserKeys(userId);
            }
            return userKey;
        });
    }
    hasUserKey(userId) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            if (userId == null) {
                return false;
            }
            return (yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.stateProvider.getUserState$(USER_KEY, userId))) != null;
        });
    }
    makeUserKey(masterKey) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            if (!masterKey) {
                throw new Error("MasterKey is required");
            }
            const newUserKey = yield this.keyGenerationService.createKey(512);
            return this.buildProtectedSymmetricKey(masterKey, newUserKey);
        });
    }
    /**
     * Clears the user key. Clears all stored versions of the user keys as well, such as the biometrics key
     * @param userId The desired user
     */
    clearUserKey(userId) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            if (userId == null) {
                // nothing to do
                return;
            }
            // Set userId to ensure we have one for the account status update
            yield this.stateProvider.setUserState(USER_KEY, null, userId);
            yield this.clearAllStoredUserKeys(userId);
        });
    }
    clearStoredUserKey(userId) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            if (userId == null) {
                throw new Error("UserId is required");
            }
            yield this.stateService.setUserKeyAutoUnlock(null, { userId: userId });
        });
    }
    /**
     * @deprecated Please use `makeMasterPasswordAuthenticationData`, `unwrapUserKeyFromMasterPasswordUnlockData` or `makeMasterPasswordUnlockData` in @link MasterPasswordService instead.
     */
    getOrDeriveMasterKey(password, userId) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            if (userId == null) {
                throw new Error("User ID is required.");
            }
            const masterKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.masterPasswordService.masterKey$(userId));
            if (masterKey != null) {
                return masterKey;
            }
            const email = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.accounts$.pipe((0,external_rxjs_namespaceObject.map)((accounts) => { var _a; return (_a = accounts[userId]) === null || _a === void 0 ? void 0 : _a.email; })));
            if (email == null) {
                throw new Error("No email found for user " + userId);
            }
            const kdf = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.kdfConfigService.getKdfConfig$(userId));
            if (kdf == null) {
                throw new Error("No kdf found for user " + userId);
            }
            return yield this.makeMasterKey(password, email, kdf);
        });
    }
    /**
     * Derive a master key from a password and email.
     *
     * @deprecated Please use `makeMasterPasswordAuthenticationData`, `makeMasterPasswordAuthenticationData`, `unwrapUserKeyFromMasterPasswordUnlockData` in @link MasterPasswordService instead.
     *
     * @remarks
     * Does not validate the kdf config to ensure it satisfies the minimum requirements for the given kdf type.
     */
    makeMasterKey(password, email, kdfConfig) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            const start = new Date().getTime();
            email = email.trim().toLowerCase();
            const masterKey = (yield this.keyGenerationService.deriveKeyFromPassword(password, email, kdfConfig));
            const end = new Date().getTime();
            this.logService.info(`[KeyService] Deriving master key took ${end - start}ms`);
            return masterKey;
        });
    }
    /**
     * @deprecated Please use `makeMasterPasswordUnlockData` in {@link MasterPasswordService} instead.
     */
    encryptUserKeyWithMasterKey(masterKey, userKey) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            if (masterKey == null) {
                throw new Error("masterKey is required.");
            }
            if (userKey == null) {
                throw new Error("userKey is required.");
            }
            return yield this.buildProtectedSymmetricKey(masterKey, userKey);
        });
    }
    /**
     * @deprecated Please use `makeMasterPasswordAuthenticationData` in {@link MasterPasswordService} instead.
     */
    hashMasterKey(password, key) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            if (password == null) {
                throw new Error("password is required.");
            }
            if (key == null) {
                throw new Error("key is required.");
            }
            // Server authorization always uses one iteration
            const iterations = 1;
            const hash = yield this.cryptoFunctionService.pbkdf2(key.inner().encryptionKey, password, "sha256", iterations);
            return utils_Utils.fromBufferToB64(hash);
        });
    }
    setOrgKeys(orgs, providerOrgs, userId) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            yield this.stateProvider.getUser(userId, org_keys_state_USER_ENCRYPTED_ORGANIZATION_KEYS).update(() => {
                const encOrgKeyData = {};
                for (const org of orgs) {
                    encOrgKeyData[org.id] = {
                        type: "organization",
                        key: org.key,
                    };
                }
                for (const org of providerOrgs) {
                    encOrgKeyData[org.id] = {
                        type: "provider",
                        providerId: org.providerId,
                        key: org.key,
                    };
                }
                return encOrgKeyData;
            });
        });
    }
    getOrgKey(orgId) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.activeUserOrgKeys$.pipe((0,external_rxjs_namespaceObject.map)((orgKeys) => { var _a; return (_a = orgKeys[orgId]) !== null && _a !== void 0 ? _a : null; })));
        });
    }
    makeDataEncKey(key) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            if (key == null) {
                throw new Error("No key provided");
            }
            // Content encryption key is AES256_CBC_HMAC
            const cek = yield this.keyGenerationService.createKey(512);
            const wrappedCek = yield this.encryptService.wrapSymmetricKey(cek, key);
            return [cek, wrappedCek];
        });
    }
    clearOrgKeys(userId) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            if (userId == null) {
                // nothing to do
                return;
            }
            yield this.stateProvider.setUserState(org_keys_state_USER_ENCRYPTED_ORGANIZATION_KEYS, null, userId);
        });
    }
    setProviderKeys(providers, userId) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            yield this.stateProvider.getUser(userId, provider_keys_state_USER_ENCRYPTED_PROVIDER_KEYS).update(() => {
                const encProviderKeys = {};
                providers.forEach((provider) => {
                    encProviderKeys[provider.id] = provider.key;
                });
                return encProviderKeys;
            });
        });
    }
    providerKeys$(userId) {
        return this.userPrivateKey$(userId).pipe((0,external_rxjs_namespaceObject.switchMap)((userPrivateKey) => {
            if (userPrivateKey == null) {
                return (0,external_rxjs_namespaceObject.of)(null);
            }
            return this.providerKeysHelper$(userId, userPrivateKey);
        }));
    }
    clearProviderKeys(userId) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            if (userId == null) {
                // nothing to do
                return;
            }
            yield this.stateProvider.setUserState(provider_keys_state_USER_ENCRYPTED_PROVIDER_KEYS, null, userId);
        });
    }
    makeOrgKey(userId) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            if (userId == null) {
                throw new Error("UserId is required");
            }
            const publicKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.userPublicKey$(userId));
            if (publicKey == null) {
                throw new Error("No public key found for user " + userId);
            }
            const shareKey = yield this.keyGenerationService.createKey(512);
            const encShareKey = yield this.encryptService.encapsulateKeyUnsigned(shareKey, publicKey);
            return [encShareKey, shareKey];
        });
    }
    getFingerprint(fingerprintMaterial, publicKey) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            if (publicKey == null) {
                throw new Error("Public key is required to generate a fingerprint.");
            }
            const keyFingerprint = yield this.cryptoFunctionService.hash(publicKey, "sha256");
            const userFingerprint = yield this.cryptoFunctionService.hkdfExpand(keyFingerprint, fingerprintMaterial, 32, "sha256");
            return this.hashPhrase(userFingerprint);
        });
    }
    makeKeyPair(key) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            if (key == null) {
                throw new Error("'key' is a required parameter and must be non-null.");
            }
            const keyPair = yield this.cryptoFunctionService.rsaGenerateKeyPair(2048);
            const publicB64 = utils_Utils.fromBufferToB64(keyPair[0]);
            const privateEnc = yield this.encryptService.wrapDecapsulationKey(keyPair[1], key);
            return [publicB64, privateEnc];
        });
    }
    makeSendKey(keyMaterial) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            return yield this.keyGenerationService.deriveKeyFromMaterial(keyMaterial, "bitwarden-send", "send");
        });
    }
    makeCipherKey() {
        return key_service_awaiter(this, void 0, void 0, function* () {
            return (yield this.keyGenerationService.createKey(512));
        });
    }
    clearKeys(userId) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            if (userId == null) {
                throw new Error("UserId is required");
            }
            yield this.clearUserKey(userId);
            yield this.clearOrgKeys(userId);
            yield this.clearProviderKeys(userId);
            yield this.stateProvider.setUserState(user_key_state_USER_EVER_HAD_USER_KEY, null, userId);
            yield this.accountCryptographyStateService.clearAccountCryptographicState(userId);
        });
    }
    // ---HELPERS---
    validateUserKey(key, userId) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            if (key == null) {
                return false;
            }
            try {
                const encPrivateKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.userEncryptedPrivateKey$(userId));
                if (encPrivateKey == null) {
                    return false;
                }
                // Can decrypt private key
                const privateKey = yield this.decryptPrivateKey(encPrivateKey, key);
                if (privateKey == null) {
                    // failed to decrypt
                    return false;
                }
                // Can successfully derive public key
                const publicKey = yield this.derivePublicKey(privateKey);
                if (publicKey == null) {
                    // failed to decrypt
                    return false;
                }
                // FIXME: Remove when updating file. Eslint update
                // eslint-disable-next-line @typescript-eslint/no-unused-vars
            }
            catch (e) {
                return false;
            }
            return true;
        });
    }
    /**
     * Initialize all necessary crypto keys needed for a new account.
     * Warning! This completely replaces any existing keys!
     */
    initAccount(userId) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            if (userId == null) {
                throw new Error("UserId is required.");
            }
            // Verify user key doesn't exist
            const existingUserKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.userKey$(userId));
            if (existingUserKey != null) {
                this.logService.error("Tried to initialize account with existing user key.");
                throw new Error("Cannot initialize account, keys already exist.");
            }
            const userKey = (yield this.keyGenerationService.createKey(512));
            const [publicKey, privateKey] = yield this.makeKeyPair(userKey);
            if (privateKey.encryptedString == null) {
                throw new Error("Failed to create valid private key.");
            }
            yield this.setUserKey(userKey, userId);
            yield this.accountCryptographyStateService.setAccountCryptographicState({
                V1: {
                    private_key: privateKey.encryptedString,
                },
            }, userId);
            return {
                userKey,
                publicKey,
                privateKey,
            };
        });
    }
    /**
     * Generates any additional keys if needed. Additional keys are
     * keys such as biometrics, auto, and pin keys.
     * Useful to make sure other keys stay in sync when the user key
     * has been rotated.
     * @param key The user key
     * @param userId The desired user
     */
    storeAdditionalKeys(key, userId) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            const storeAuto = yield this.shouldStoreKey(KeySuffixOptions.Auto, userId);
            if (storeAuto) {
                yield this.stateService.setUserKeyAutoUnlock(key.keyB64, { userId: userId });
            }
            else {
                yield this.stateService.setUserKeyAutoUnlock(null, { userId: userId });
            }
        });
    }
    shouldStoreKey(keySuffix, userId) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            switch (keySuffix) {
                case KeySuffixOptions.Auto: {
                    // Cli has fixed Never vault timeout, and it should not be affected by a policy.
                    if (this.platformUtilService.getClientType() == src_ClientType.Cli) {
                        return true;
                    }
                    // TODO: Sharing the UserKeyDefinition is temporary to get around a circ dep issue between
                    // the VaultTimeoutSettingsSvc and this service.
                    // This should be fixed as part of the PM-7082 - Auto Key Service work.
                    const vaultTimeout = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.stateProvider
                        .getUserState$(vault_timeout_settings_state_VAULT_TIMEOUT, userId)
                        .pipe((0,external_rxjs_namespaceObject.filter)((timeout) => timeout != null)));
                    this.logService.debug(`[KeyService] Should store auto key for vault timeout ${vaultTimeout}`);
                    return vaultTimeout == VaultTimeoutStringType.Never;
                }
            }
            return false;
        });
    }
    getKeyFromStorage(keySuffix, userId) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            if (keySuffix === KeySuffixOptions.Auto) {
                const userKey = yield this.stateService.getUserKeyAutoUnlock({ userId: userId });
                if (userKey) {
                    return new SymmetricCryptoKey(utils_Utils.fromB64ToArray(userKey));
                }
            }
            return null;
        });
    }
    clearAllStoredUserKeys(userId) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            yield this.stateService.setUserKeyAutoUnlock(null, { userId: userId });
        });
    }
    hashPhrase(hash_1) {
        return key_service_awaiter(this, arguments, void 0, function* (hash, minimumEntropy = 64) {
            const entropyPerWord = Math.log(EFFLongWordList.length) / Math.log(2);
            let numWords = Math.ceil(minimumEntropy / entropyPerWord);
            const hashArr = Array.from(new Uint8Array(hash));
            const entropyAvailable = hashArr.length * 4;
            if (numWords * entropyPerWord > entropyAvailable) {
                throw new Error("Output entropy of hash function is too small");
            }
            const phrase = [];
            let hashNumber = external_big_integer_namespaceObject.fromArray(hashArr, 256);
            while (numWords--) {
                const remainder = hashNumber.mod(EFFLongWordList.length);
                hashNumber = hashNumber.divide(EFFLongWordList.length);
                phrase.push(EFFLongWordList[remainder]);
            }
            return phrase;
        });
    }
    /**
     * @deprecated
     * This should only be used for wrapping the user key with a master key or stretched master key.
     */
    buildProtectedSymmetricKey(encryptionKey, newSymKey) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            let protectedSymKey;
            if (encryptionKey.inner().type === encryption_type_enum_EncryptionType.AesCbc256_B64) {
                const stretchedEncryptionKey = yield this.keyGenerationService.stretchKey(encryptionKey);
                protectedSymKey = yield this.encryptService.wrapSymmetricKey(newSymKey, stretchedEncryptionKey);
            }
            else if (encryptionKey.inner().type === encryption_type_enum_EncryptionType.AesCbc256_HmacSha256_B64) {
                protectedSymKey = yield this.encryptService.wrapSymmetricKey(newSymKey, encryptionKey);
            }
            else {
                throw new Error("Invalid key size.");
            }
            return [newSymKey, protectedSymKey];
        });
    }
    userKey$(userId) {
        return this.stateProvider
            .getUser(userId, USER_KEY)
            .state$.pipe((0,external_rxjs_namespaceObject.map)((key) => (key != null ? key[""] : null)));
    }
    userPublicKey$(userId) {
        return this.userPrivateKey$(userId).pipe((0,external_rxjs_namespaceObject.switchMap)((pk) => key_service_awaiter(this, void 0, void 0, function* () { return yield this.derivePublicKey(pk); })));
    }
    derivePublicKey(privateKey) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            if (privateKey == null) {
                return null;
            }
            return yield this.cryptoFunctionService.rsaExtractPublicKey(privateKey);
        });
    }
    userPrivateKey$(userId) {
        return this.userPrivateKeyHelper$(userId).pipe((0,external_rxjs_namespaceObject.map)((keys) => { var _a; return (_a = keys === null || keys === void 0 ? void 0 : keys.userPrivateKey) !== null && _a !== void 0 ? _a : null; }));
    }
    userEncryptionKeyPair$(userId) {
        return this.userPrivateKey$(userId).pipe((0,external_rxjs_namespaceObject.switchMap)((privateKey) => key_service_awaiter(this, void 0, void 0, function* () {
            if (privateKey == null) {
                return null;
            }
            const publicKey = (yield this.derivePublicKey(privateKey));
            return { privateKey, publicKey };
        })));
    }
    userEncryptedPrivateKey$(userId) {
        return this.accountCryptographyStateService.accountCryptographicState$(userId).pipe((0,external_rxjs_namespaceObject.map)((state) => {
            if (state == null) {
                return null;
            }
            if ("V2" in state) {
                return state.V2.private_key;
            }
            else if ("V1" in state) {
                return state.V1.private_key;
            }
            else {
                return null;
            }
        }));
    }
    userPrivateKeyHelper$(userId) {
        const userKey$ = this.userKey$(userId);
        return userKey$.pipe((0,external_rxjs_namespaceObject.switchMap)((userKey) => {
            if (userKey == null) {
                return (0,external_rxjs_namespaceObject.of)(null);
            }
            return this.userEncryptedPrivateKey$(userId).pipe((0,external_rxjs_namespaceObject.switchMap)((encryptedPrivateKey) => key_service_awaiter(this, void 0, void 0, function* () {
                return yield this.decryptPrivateKey(encryptedPrivateKey, userKey);
            })), 
            // Combine outerscope info with user private key
            (0,external_rxjs_namespaceObject.map)((userPrivateKey) => ({
                userKey,
                userPrivateKey,
            })), (0,external_rxjs_namespaceObject.catchError)((err) => {
                this.logService.error(`Failed to decrypt private key for user ${userId}`);
                return (0,external_rxjs_namespaceObject.of)({
                    userKey,
                    userPrivateKey: null,
                });
            }));
        }));
    }
    decryptPrivateKey(encryptedPrivateKey, key) {
        return key_service_awaiter(this, void 0, void 0, function* () {
            if (encryptedPrivateKey == null) {
                return null;
            }
            return (yield this.encryptService.unwrapDecapsulationKey(new enc_string_EncString(encryptedPrivateKey), key));
        });
    }
    /**
     * A helper for decrypting provider keys that requires a user id and that users decrypted private key
     * this is helpful for when you may have already grabbed the user private key and don't want to redo
     * that work to get the provider keys.
     */
    providerKeysHelper$(userId, userPrivateKey) {
        return this.stateProvider.getUser(userId, provider_keys_state_USER_ENCRYPTED_PROVIDER_KEYS).state$.pipe(
        // Convert each value in the record to it's own decryption observable
        convertValues((_, value) => key_service_awaiter(this, void 0, void 0, function* () {
            const decapsulatedKey = yield this.encryptService.decapsulateKeyUnsigned(new enc_string_EncString(value), userPrivateKey);
            return decapsulatedKey;
        })), 
        // switchMap since there are no side effects
        (0,external_rxjs_namespaceObject.switchMap)((encryptedProviderKeys) => {
            if (encryptedProviderKeys == null) {
                return (0,external_rxjs_namespaceObject.of)(null);
            }
            // Can't give an empty record to forkJoin
            if (Object.keys(encryptedProviderKeys).length === 0) {
                return (0,external_rxjs_namespaceObject.of)({});
            }
            return (0,external_rxjs_namespaceObject.forkJoin)(encryptedProviderKeys);
        }));
    }
    userSigningKey$(userId) {
        return this.accountCryptographyStateService.accountCryptographicState$(userId).pipe((0,external_rxjs_namespaceObject.map)((state) => {
            if (state == null) {
                return null;
            }
            if ("V2" in state) {
                return state.V2.signing_key;
            }
            else {
                return null;
            }
        }));
    }
    orgKeys$(userId) {
        return this.cipherDecryptionKeys$(userId).pipe((0,external_rxjs_namespaceObject.map)((keys) => { var _a; return (_a = keys === null || keys === void 0 ? void 0 : keys.orgKeys) !== null && _a !== void 0 ? _a : null; }));
    }
    encryptedOrgKeys$(userId) {
        var _a;
        return (_a = this.userPrivateKey$(userId)) === null || _a === void 0 ? void 0 : _a.pipe((0,external_rxjs_namespaceObject.switchMap)((userPrivateKey) => {
            if (userPrivateKey == null) {
                // We can't do any org based decryption
                return (0,external_rxjs_namespaceObject.of)({});
            }
            return (0,external_rxjs_namespaceObject.combineLatest)([
                this.stateProvider.getUser(userId, org_keys_state_USER_ENCRYPTED_ORGANIZATION_KEYS).state$,
                this.providerKeysHelper$(userId, userPrivateKey),
            ]).pipe((0,external_rxjs_namespaceObject.switchMap)((_a) => key_service_awaiter(this, [_a], void 0, function* ([encryptedOrgKeys, providerKeys]) {
                const userPubKey = yield this.derivePublicKey(userPrivateKey);
                const result = {};
                encryptedOrgKeys = encryptedOrgKeys !== null && encryptedOrgKeys !== void 0 ? encryptedOrgKeys : {};
                for (const orgId of Object.keys(encryptedOrgKeys)) {
                    if (result[orgId] != null) {
                        continue;
                    }
                    const encrypted = BaseEncryptedOrganizationKey.fromData(encryptedOrgKeys[orgId]);
                    if (encrypted == null) {
                        continue;
                    }
                    let orgKey;
                    // Because the SDK only supports user encrypted org keys, we need to re-encrypt
                    // any provider encrypted org keys with the user's public key. This should be removed
                    // once the SDK has support for provider keys.
                    if (BaseEncryptedOrganizationKey.isProviderEncrypted(encrypted)) {
                        if (providerKeys == null) {
                            continue;
                        }
                        orgKey = yield this.encryptService.encapsulateKeyUnsigned(yield encrypted.decrypt(this.encryptService, providerKeys), userPubKey);
                    }
                    else {
                        orgKey = encrypted.encryptedOrganizationKey;
                    }
                    result[orgId] = orgKey;
                }
                return result;
            })), (0,external_rxjs_namespaceObject.catchError)((err) => {
                this.logService.error(`Failed to get encrypted organization keys for user ${userId}`, err);
                return (0,external_rxjs_namespaceObject.of)({});
            }));
        }));
    }
    cipherDecryptionKeys$(userId) {
        var _a;
        return (_a = this.userPrivateKeyHelper$(userId)) === null || _a === void 0 ? void 0 : _a.pipe((0,external_rxjs_namespaceObject.switchMap)((userKeys) => {
            if (userKeys == null) {
                return (0,external_rxjs_namespaceObject.of)(null);
            }
            const userPrivateKey = userKeys.userPrivateKey;
            if (userPrivateKey == null) {
                // We can't do any org based decryption
                return (0,external_rxjs_namespaceObject.of)({ userKey: userKeys.userKey, orgKeys: null });
            }
            return (0,external_rxjs_namespaceObject.combineLatest)([
                this.stateProvider.getUser(userId, org_keys_state_USER_ENCRYPTED_ORGANIZATION_KEYS).state$,
                this.providerKeysHelper$(userId, userPrivateKey),
            ]).pipe((0,external_rxjs_namespaceObject.switchMap)((_a) => key_service_awaiter(this, [_a], void 0, function* ([encryptedOrgKeys, providerKeys]) {
                const result = {};
                encryptedOrgKeys = encryptedOrgKeys !== null && encryptedOrgKeys !== void 0 ? encryptedOrgKeys : {};
                for (const orgId of Object.keys(encryptedOrgKeys)) {
                    if (result[orgId] != null) {
                        continue;
                    }
                    const encrypted = BaseEncryptedOrganizationKey.fromData(encryptedOrgKeys[orgId]);
                    if (encrypted == null) {
                        continue;
                    }
                    let decrypted;
                    if (BaseEncryptedOrganizationKey.isProviderEncrypted(encrypted)) {
                        if (providerKeys == null) {
                            continue;
                        }
                        decrypted = yield encrypted.decrypt(this.encryptService, providerKeys);
                    }
                    else {
                        decrypted = yield encrypted.decrypt(this.encryptService, userPrivateKey);
                    }
                    result[orgId] = decrypted;
                }
                return result;
            })), 
            // Combine them back together
            (0,external_rxjs_namespaceObject.map)((orgKeys) => ({ userKey: userKeys.userKey, orgKeys: orgKeys })));
        }));
    }
    userSignedPublicKey$(userId) {
        return this.accountCryptographyStateService.accountCryptographicState$(userId).pipe((0,external_rxjs_namespaceObject.map)((state) => {
            if (state == null) {
                return null;
            }
            if ("V2" in state) {
                return state.V2.signed_public_key;
            }
            else {
                return null;
            }
        }));
    }
    userKeyToStateObject(userKey) {
        if (userKey == null) {
            return null;
        }
        return { [USER_KEY_STATE_KEY]: userKey };
    }
    stateObjectToUserKey(stateObject) {
        var _a;
        if (stateObject == null) {
            return null;
        }
        return (_a = stateObject[USER_KEY_STATE_KEY]) !== null && _a !== void 0 ? _a : null;
    }
}

;// ../../libs/common/src/auth/utils/assert-non-nullish.util.ts
/**
 * Asserts that a value is non-nullish (not `null` or `undefined`); throws if value is nullish.
 *
 * @param val the value to check
 * @param name the name of the value to include in the error message
 * @param ctx context to optionally append to the error message
 * @throws if the value is null or undefined
 *
 * @example
 *
 * ```
 *    // `newPasswordHint` can have an empty string as a valid value, so we check non-nullish
 *    this.assertNonNullish(
 *      passwordInputResult.newPasswordHint,
 *      "newPasswordHint",
 *      "Could not set initial password."
 *    );
 *    // Output error message: "newPasswordHint is null or undefined. Could not set initial password."
 * ```
 *
 * @remarks
 *
 * If you use this method repeatedly to check several values, it may help to assign any
 * additional context (`ctx`) to a variable and pass it in to each call. This prevents the
 * call from reformatting vertically via prettier in your text editor, taking up multiple lines.
 *
 * For example:
 * ```
 *    const ctx = "Could not set initial password.";
 *
 *    this.assertNonNullish(valueOne, "valueOne", ctx);
 *    this.assertNonNullish(valueTwo, "valueTwo", ctx);
 *    this.assertNonNullish(valueThree, "valueThree", ctx);
 * ```
 */
function assertNonNullish(val, name, ctx) {
    if (val == null) {
        // If context is provided, append it to the error message with a space before it.
        throw new Error(`${name} is null or undefined.${ctx ? ` ${ctx}` : ""}`);
    }
}

;// ../../libs/common/src/platform/misc/range-with-default.ts
/**
 * A range with a default value.
 *
 * Enforces constraints to ensure min > default > max.
 */
class RangeWithDefault {
    constructor(min, max, defaultValue) {
        this.min = min;
        this.max = max;
        this.defaultValue = defaultValue;
        if (min > max) {
            throw new Error(`${min} is greater than ${max}.`);
        }
        if (this.inRange(defaultValue) === false) {
            throw new Error("Default value is not in range.");
        }
    }
    inRange(value) {
        return value >= this.min && value <= this.max;
    }
}

;// ../../libs/key-management/src/enums/kdf-type.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var kdf_type_enum_KdfType;
(function (KdfType) {
    KdfType[KdfType["PBKDF2_SHA256"] = 0] = "PBKDF2_SHA256";
    KdfType[KdfType["Argon2id"] = 1] = "Argon2id";
})(kdf_type_enum_KdfType || (kdf_type_enum_KdfType = {}));

;// ../../libs/key-management/src/models/kdf-config.ts



/**
 * Password-Based Key Derivation Function 2 (PBKDF2) KDF configuration.
 */
class PBKDF2KdfConfig {
    constructor(iterations) {
        this.iterations = iterations;
        this.kdfType = kdf_type_enum_KdfType.PBKDF2_SHA256;
        assertNonNullish(iterations, "iterations");
    }
    static createDefault() {
        return new PBKDF2KdfConfig(PBKDF2KdfConfig.ITERATIONS.defaultValue);
    }
    /**
     * Validates the PBKDF2 KDF configuration for updating the KDF config.
     * A Valid PBKDF2 KDF configuration has KDF iterations between the 600_000 and 2_000_000.
     */
    validateKdfConfigForSetting() {
        if (!PBKDF2KdfConfig.ITERATIONS.inRange(this.iterations)) {
            throw new Error(`PBKDF2 iterations must be between ${PBKDF2KdfConfig.ITERATIONS.min} and ${PBKDF2KdfConfig.ITERATIONS.max}`);
        }
    }
    /**
     * Validates the PBKDF2 KDF configuration for pre-login.
     * A Valid PBKDF2 KDF configuration has KDF iterations between the 5000 and 2_000_000.
     */
    validateKdfConfigForPrelogin() {
        if (PBKDF2KdfConfig.PRELOGIN_ITERATIONS_MIN > this.iterations) {
            throw new Error(`PBKDF2 iterations must be at least ${PBKDF2KdfConfig.PRELOGIN_ITERATIONS_MIN}, but was ${this.iterations}; possible pre-login downgrade attack detected.`);
        }
    }
    static fromJSON(json) {
        return new PBKDF2KdfConfig(json.iterations);
    }
    toSdkConfig() {
        return {
            pBKDF2: {
                iterations: this.iterations,
            },
        };
    }
}
PBKDF2KdfConfig.ITERATIONS = new RangeWithDefault(600000, 2000000, 600000);
PBKDF2KdfConfig.PRELOGIN_ITERATIONS_MIN = 5000;
/**
 * Argon2 KDF configuration.
 */
class Argon2KdfConfig {
    constructor(iterations, memory, parallelism) {
        this.iterations = iterations;
        this.memory = memory;
        this.parallelism = parallelism;
        this.kdfType = kdf_type_enum_KdfType.Argon2id;
        assertNonNullish(iterations, "iterations");
        assertNonNullish(memory, "memory");
        assertNonNullish(parallelism, "parallelism");
    }
    static createDefault() {
        return new Argon2KdfConfig(Argon2KdfConfig.ITERATIONS.defaultValue, Argon2KdfConfig.MEMORY.defaultValue, Argon2KdfConfig.PARALLELISM.defaultValue);
    }
    /**
     * Validates the Argon2 KDF configuration for updating the KDF config.
     * A Valid Argon2 KDF configuration has iterations between 2 and 10, memory between 16mb and 1024mb, and parallelism between 1 and 16.
     */
    validateKdfConfigForSetting() {
        if (!Argon2KdfConfig.ITERATIONS.inRange(this.iterations)) {
            throw new Error(`Argon2 iterations must be between ${Argon2KdfConfig.ITERATIONS.min} and ${Argon2KdfConfig.ITERATIONS.max}`);
        }
        if (!Argon2KdfConfig.MEMORY.inRange(this.memory)) {
            throw new Error(`Argon2 memory must be between ${Argon2KdfConfig.MEMORY.min} MiB and ${Argon2KdfConfig.MEMORY.max} MiB`);
        }
        if (!Argon2KdfConfig.PARALLELISM.inRange(this.parallelism)) {
            throw new Error(`Argon2 parallelism must be between ${Argon2KdfConfig.PARALLELISM.min} and ${Argon2KdfConfig.PARALLELISM.max}.`);
        }
    }
    /**
     * Validates the Argon2 KDF configuration for pre-login.
     */
    validateKdfConfigForPrelogin() {
        if (Argon2KdfConfig.PRELOGIN_ITERATIONS_MIN > this.iterations) {
            throw new Error(`Argon2 iterations must be at least ${Argon2KdfConfig.PRELOGIN_ITERATIONS_MIN}, but was ${this.iterations}; possible pre-login downgrade attack detected.`);
        }
        if (Argon2KdfConfig.PRELOGIN_MEMORY_MIN > this.memory) {
            throw new Error(`Argon2 memory must be at least ${Argon2KdfConfig.PRELOGIN_MEMORY_MIN} MiB, but was ${this.memory} MiB; possible pre-login downgrade attack detected.`);
        }
        if (Argon2KdfConfig.PRELOGIN_PARALLELISM_MIN > this.parallelism) {
            throw new Error(`Argon2 parallelism must be at least ${Argon2KdfConfig.PRELOGIN_PARALLELISM_MIN}, but was ${this.parallelism}; possible pre-login downgrade attack detected.`);
        }
    }
    static fromJSON(json) {
        return new Argon2KdfConfig(json.iterations, json.memory, json.parallelism);
    }
    toSdkConfig() {
        return {
            argon2id: {
                iterations: this.iterations,
                memory: this.memory,
                parallelism: this.parallelism,
            },
        };
    }
}
Argon2KdfConfig.MEMORY = new RangeWithDefault(16, 1024, 32);
Argon2KdfConfig.PARALLELISM = new RangeWithDefault(1, 16, 4);
Argon2KdfConfig.ITERATIONS = new RangeWithDefault(2, 10, 6);
Argon2KdfConfig.PRELOGIN_MEMORY_MIN = 16;
Argon2KdfConfig.PRELOGIN_PARALLELISM_MIN = 1;
Argon2KdfConfig.PRELOGIN_ITERATIONS_MIN = 2;
function fromSdkKdfConfig(sdkKdf) {
    if ("pBKDF2" in sdkKdf) {
        return new PBKDF2KdfConfig(sdkKdf.pBKDF2.iterations);
    }
    else if ("argon2id" in sdkKdf) {
        return new Argon2KdfConfig(sdkKdf.argon2id.iterations, sdkKdf.argon2id.memory, sdkKdf.argon2id.parallelism);
    }
    else {
        throw new Error("Unsupported KDF type");
    }
}
const DEFAULT_KDF_CONFIG = new PBKDF2KdfConfig(PBKDF2KdfConfig.ITERATIONS.defaultValue);

;// ../../libs/key-management/src/kdf-config.service.ts
var kdf_config_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};




const KDF_CONFIG = new UserKeyDefinition(KDF_CONFIG_DISK, "kdfConfig", {
    deserializer: (kdfConfig) => {
        if (kdfConfig == null) {
            return null;
        }
        return kdfConfig.kdfType === kdf_type_enum_KdfType.PBKDF2_SHA256
            ? PBKDF2KdfConfig.fromJSON(kdfConfig)
            : Argon2KdfConfig.fromJSON(kdfConfig);
    },
    clearOn: ["logout"],
});
class DefaultKdfConfigService {
    constructor(stateProvider) {
        this.stateProvider = stateProvider;
    }
    setKdfConfig(userId, kdfConfig) {
        return kdf_config_service_awaiter(this, void 0, void 0, function* () {
            if (userId == null) {
                throw new Error("userId cannot be null");
            }
            if (kdfConfig == null) {
                throw new Error("kdfConfig cannot be null");
            }
            yield this.stateProvider.setUserState(KDF_CONFIG, kdfConfig, userId);
        });
    }
    getKdfConfig(userId) {
        return kdf_config_service_awaiter(this, void 0, void 0, function* () {
            if (userId == null) {
                throw new Error("userId cannot be null");
            }
            const state = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.stateProvider.getUser(userId, KDF_CONFIG).state$);
            if (state == null) {
                throw new Error("KdfConfig for user " + userId + " is null");
            }
            return state;
        });
    }
    getKdfConfig$(userId) {
        if (userId == null) {
            throw new Error("userId cannot be null");
        }
        return this.stateProvider.getUser(userId, KDF_CONFIG).state$;
    }
}

;// ../../libs/common/src/enums/feature-flag.enum.ts
/**
 * Feature flags.
 *
 * Flags MUST be short lived and SHALL be removed once enabled.
 *
 * Flags should be grouped by team to have visibility of ownership and cleanup.
 */
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var feature_flag_enum_FeatureFlag;
(function (FeatureFlag) {
    /* Admin Console Team */
    FeatureFlag["AdminResetTwoFactor"] = "pm-15489-reset-two-factor-account-recovery";
    FeatureFlag["GenerateInviteLink"] = "pm-32497-generate-invite-link";
    FeatureFlag["PolicyDrawers"] = "pm-34804-policy-drawers";
    /* Auth */
    FeatureFlag["PM27086_UpdateAuthenticationApisForInputPassword"] = "pm-27086-update-authentication-apis-for-input-password";
    FeatureFlag["SafariAccountSwitching"] = "pm-5594-safari-account-switching";
    FeatureFlag["PM30811_ChangeEmailNewAuthenticationApis"] = "pm-30811-change-email-new-authentication-apis";
    FeatureFlag["PM31088_MasterPasswordServiceEmitSalt"] = "pm-31088-master-password-service-emit-salt";
    FeatureFlag["UseUnlockServiceForPasswordLogin"] = "use-unlock-service-for-password-login";
    FeatureFlag["PM32413_MultiClientPasswordManagement"] = "pm-32413-multi-client-password-management";
    // TODO: PM-34091 - Remove this flag and its DefaultFeatureFlagValue entry below.
    FeatureFlag["PM4516_DevicesLastActivityDate"] = "pm-4516-devices-add-last-activity-date";
    /* Autofill */
    FeatureFlag["UseUndeterminedCipherScenarioTriggeringLogic"] = "undetermined-cipher-scenario-logic";
    FeatureFlag["MacOsNativeCredentialSync"] = "macos-native-credential-sync";
    FeatureFlag["WindowsDesktopAutotype"] = "windows-desktop-autotype";
    FeatureFlag["WindowsDesktopAutotypeGA"] = "windows-desktop-autotype-ga";
    FeatureFlag["SSHAgentV2"] = "ssh-agent-v2";
    FeatureFlag["FillAssistTargetingRules"] = "fill-assist-targeting-rules";
    /* Billing */
    FeatureFlag["PM29108_EnablePersonalDiscounts"] = "pm-29108-enable-personal-discounts";
    FeatureFlag["PM24032_NewNavigationPremiumUpgradeButton"] = "pm-24032-new-navigation-premium-upgrade-button";
    FeatureFlag["PM23713_PremiumBadgeOpensNewPremiumUpgradeDialog"] = "pm-23713-premium-badge-opens-new-premium-upgrade-dialog";
    FeatureFlag["PM29594_UpdateIndividualSubscriptionPage"] = "pm-29594-update-individual-subscription-page";
    FeatureFlag["PM29593_PremiumToOrganizationUpgrade"] = "pm-29593-premium-to-organization-upgrade";
    /* Key Management */
    FeatureFlag["PrivateKeyRegeneration"] = "pm-12241-private-key-regeneration";
    FeatureFlag["EnrollAeadOnKeyRotation"] = "enroll-aead-on-key-rotation";
    FeatureFlag["ForceUpdateKDFSettings"] = "pm-18021-force-update-kdf-settings";
    FeatureFlag["SdkKeyRotation"] = "pm-30144-sdk-key-rotation";
    FeatureFlag["LinuxBiometricsV2"] = "pm-26340-linux-biometrics-v2";
    FeatureFlag["NoLogoutOnKdfChange"] = "pm-23995-no-logout-on-kdf-change";
    FeatureFlag["PasskeyUnlock"] = "pm-2035-passkey-unlock";
    FeatureFlag["PM27279_V2RegistrationTdeJit"] = "pm-27279-v2-registration-tde-jit";
    FeatureFlag["EnableAccountEncryptionV2KeyConnectorRegistration"] = "enable-account-encryption-v2-key-connector-registration";
    FeatureFlag["EnableAccountEncryptionV2JitPasswordRegistration"] = "enable-account-encryption-v2-jit-password-registration";
    FeatureFlag["UnlockKeyConnectorWithSdk"] = "use-unlock-service-for-key-connector-login";
    FeatureFlag["SdkKeyConnectorMigration"] = "use-sdk-for-key-connector-migration";
    FeatureFlag["UnlockViaSDK"] = "unlock-via-sdk";
    /* Tools */
    FeatureFlag["UseSdkPasswordGenerators"] = "pm-19976-use-sdk-password-generators";
    FeatureFlag["SendUIRefresh"] = "pm-28175-send-ui-refresh";
    FeatureFlag["SendEmailOTP"] = "pm-19051-send-email-verification";
    FeatureFlag["SendControls"] = "pm-31885-send-controls";
    /* DIRT */
    FeatureFlag["EventManagementForBlumira"] = "event-management-for-blumira";
    FeatureFlag["EventManagementForDataDogAndCrowdStrike"] = "event-management-for-datadog-and-crowdstrike";
    FeatureFlag["EventManagementForHuntress"] = "event-management-for-huntress";
    FeatureFlag["PhishingDetection"] = "phishing-detection";
    FeatureFlag["Milestone11AppPageImprovements"] = "pm-30538-dirt-milestone-11-app-page-improvements";
    FeatureFlag["AccessIntelligenceTrendChart"] = "pm-26961-access-intelligence-trend-chart";
    FeatureFlag["AccessIntelligenceNewArchitecture"] = "pm-31936-access-intelligence-new-architecture";
    /* Vault */
    FeatureFlag["PM32009NewItemTypes"] = "pm-32009-new-item-types";
    FeatureFlag["PM19941MigrateCipherDomainToSdk"] = "pm-19941-migrate-cipher-domain-to-sdk";
    FeatureFlag["PM22134SdkCipherListView"] = "pm-22134-sdk-cipher-list-view";
    FeatureFlag["PM22136_SdkCipherEncryption"] = "pm-22136-sdk-cipher-encryption";
    FeatureFlag["CipherKeyEncryption"] = "cipher-key-encryption";
    FeatureFlag["MigrateMyVaultToMyItems"] = "pm-20558-migrate-myvault-to-myitems";
    FeatureFlag["PM27632_SdkCipherCrudOperations"] = "pm-27632-cipher-crud-operations-to-sdk";
    FeatureFlag["PM30521_AutofillButtonViewLoginScreen"] = "pm-30521-autofill-button-view-login-screen";
    FeatureFlag["PM29438_WelcomeDialogWithExtensionPrompt"] = "pm-29438-welcome-dialog-with-extension-prompt";
    FeatureFlag["PM29438_DialogWithExtensionPromptAccountAge"] = "pm-29438-dialog-with-extension-prompt-account-age";
    FeatureFlag["PM29437_WelcomeDialog"] = "pm-29437-welcome-dialog-no-ext-prompt";
    FeatureFlag["PM31039ItemActionInExtension"] = "pm-31039-item-action-in-extension";
    FeatureFlag["PM32180PremiumUpsellAccountAge"] = "pm-32180-premium-upsell-account-age";
    FeatureFlag["PM28091_AddCopyAndQuickLaunchActions"] = "pm-28091-add-copy-and-quick-launch-actions";
    FeatureFlag["PM34500_StrictCipherDecryption"] = "pm-34500-strict-cipher-decryption";
    /* Platform */
    FeatureFlag["ContentScriptIpcChannelFramework"] = "content-script-ipc-channel-framework";
    FeatureFlag["WebAuthnRelatedOrigins"] = "pm-30529-webauthn-related-origins";
    FeatureFlag["PM34410AttachmentUploadProgress"] = "pm-34410-attachment-upload-progress";
    /* Innovation */
    FeatureFlag["ElectronStorageCache"] = "pm-32783-electron-storage-cache";
    /* Desktop */
    FeatureFlag["DesktopUiMigrationMilestone3"] = "desktop-ui-migration-milestone-3";
    FeatureFlag["DesktopUiMigrationMilestone4"] = "desktop-ui-migration-milestone-4";
})(feature_flag_enum_FeatureFlag || (feature_flag_enum_FeatureFlag = {}));
// Helper to ensure the value is treated as a boolean.
const FALSE = false;
/**
 * Default value for feature flags.
 *
 * DO NOT enable previously disabled flags, REMOVE them instead.
 * We support true as a value as we prefer flags to "enable" not "disable".
 *
 * Flags should be grouped by team to have visibility of ownership and cleanup.
 */
const DefaultFeatureFlagValue = {
    /* Admin Console Team */
    [feature_flag_enum_FeatureFlag.AdminResetTwoFactor]: FALSE,
    [feature_flag_enum_FeatureFlag.GenerateInviteLink]: FALSE,
    [feature_flag_enum_FeatureFlag.PolicyDrawers]: FALSE,
    /* Autofill */
    [feature_flag_enum_FeatureFlag.FillAssistTargetingRules]: FALSE,
    [feature_flag_enum_FeatureFlag.UseUndeterminedCipherScenarioTriggeringLogic]: FALSE,
    [feature_flag_enum_FeatureFlag.MacOsNativeCredentialSync]: FALSE,
    [feature_flag_enum_FeatureFlag.WindowsDesktopAutotype]: FALSE,
    [feature_flag_enum_FeatureFlag.WindowsDesktopAutotypeGA]: FALSE,
    [feature_flag_enum_FeatureFlag.SSHAgentV2]: FALSE,
    [feature_flag_enum_FeatureFlag.PM31039ItemActionInExtension]: FALSE,
    /* Tools */
    [feature_flag_enum_FeatureFlag.UseSdkPasswordGenerators]: FALSE,
    [feature_flag_enum_FeatureFlag.SendUIRefresh]: FALSE,
    [feature_flag_enum_FeatureFlag.SendEmailOTP]: FALSE,
    [feature_flag_enum_FeatureFlag.SendControls]: FALSE,
    /* DIRT */
    [feature_flag_enum_FeatureFlag.EventManagementForBlumira]: FALSE,
    [feature_flag_enum_FeatureFlag.EventManagementForDataDogAndCrowdStrike]: FALSE,
    [feature_flag_enum_FeatureFlag.EventManagementForHuntress]: FALSE,
    [feature_flag_enum_FeatureFlag.PhishingDetection]: FALSE,
    [feature_flag_enum_FeatureFlag.Milestone11AppPageImprovements]: FALSE,
    [feature_flag_enum_FeatureFlag.AccessIntelligenceTrendChart]: FALSE,
    [feature_flag_enum_FeatureFlag.AccessIntelligenceNewArchitecture]: FALSE,
    /* Vault */
    [feature_flag_enum_FeatureFlag.PM32009NewItemTypes]: FALSE,
    [feature_flag_enum_FeatureFlag.CipherKeyEncryption]: FALSE,
    [feature_flag_enum_FeatureFlag.PM19941MigrateCipherDomainToSdk]: FALSE,
    [feature_flag_enum_FeatureFlag.PM22134SdkCipherListView]: FALSE,
    [feature_flag_enum_FeatureFlag.PM22136_SdkCipherEncryption]: FALSE,
    [feature_flag_enum_FeatureFlag.PM27632_SdkCipherCrudOperations]: FALSE,
    [feature_flag_enum_FeatureFlag.MigrateMyVaultToMyItems]: FALSE,
    [feature_flag_enum_FeatureFlag.PM30521_AutofillButtonViewLoginScreen]: FALSE,
    [feature_flag_enum_FeatureFlag.PM29438_WelcomeDialogWithExtensionPrompt]: FALSE,
    [feature_flag_enum_FeatureFlag.PM29438_DialogWithExtensionPromptAccountAge]: 5,
    [feature_flag_enum_FeatureFlag.PM29437_WelcomeDialog]: FALSE,
    [feature_flag_enum_FeatureFlag.PM32180PremiumUpsellAccountAge]: 7,
    [feature_flag_enum_FeatureFlag.PM28091_AddCopyAndQuickLaunchActions]: FALSE,
    [feature_flag_enum_FeatureFlag.PM34500_StrictCipherDecryption]: FALSE,
    /* Auth */
    [feature_flag_enum_FeatureFlag.PM27086_UpdateAuthenticationApisForInputPassword]: FALSE,
    [feature_flag_enum_FeatureFlag.SafariAccountSwitching]: FALSE,
    [feature_flag_enum_FeatureFlag.PM30811_ChangeEmailNewAuthenticationApis]: FALSE,
    [feature_flag_enum_FeatureFlag.PM31088_MasterPasswordServiceEmitSalt]: FALSE,
    [feature_flag_enum_FeatureFlag.UseUnlockServiceForPasswordLogin]: FALSE,
    [feature_flag_enum_FeatureFlag.PM32413_MultiClientPasswordManagement]: FALSE,
    // TODO: PM-34091 - Remove this default value entry.
    [feature_flag_enum_FeatureFlag.PM4516_DevicesLastActivityDate]: FALSE,
    /* Billing */
    [feature_flag_enum_FeatureFlag.PM29108_EnablePersonalDiscounts]: FALSE,
    [feature_flag_enum_FeatureFlag.PM24032_NewNavigationPremiumUpgradeButton]: FALSE,
    [feature_flag_enum_FeatureFlag.PM23713_PremiumBadgeOpensNewPremiumUpgradeDialog]: FALSE,
    [feature_flag_enum_FeatureFlag.PM29594_UpdateIndividualSubscriptionPage]: FALSE,
    [feature_flag_enum_FeatureFlag.PM29593_PremiumToOrganizationUpgrade]: FALSE,
    /* Key Management */
    [feature_flag_enum_FeatureFlag.PrivateKeyRegeneration]: FALSE,
    [feature_flag_enum_FeatureFlag.EnrollAeadOnKeyRotation]: FALSE,
    [feature_flag_enum_FeatureFlag.ForceUpdateKDFSettings]: FALSE,
    [feature_flag_enum_FeatureFlag.SdkKeyRotation]: FALSE,
    [feature_flag_enum_FeatureFlag.LinuxBiometricsV2]: FALSE,
    [feature_flag_enum_FeatureFlag.NoLogoutOnKdfChange]: FALSE,
    [feature_flag_enum_FeatureFlag.PasskeyUnlock]: FALSE,
    [feature_flag_enum_FeatureFlag.PM27279_V2RegistrationTdeJit]: FALSE,
    [feature_flag_enum_FeatureFlag.EnableAccountEncryptionV2KeyConnectorRegistration]: FALSE,
    [feature_flag_enum_FeatureFlag.EnableAccountEncryptionV2JitPasswordRegistration]: FALSE,
    [feature_flag_enum_FeatureFlag.UnlockKeyConnectorWithSdk]: FALSE,
    [feature_flag_enum_FeatureFlag.SdkKeyConnectorMigration]: FALSE,
    [feature_flag_enum_FeatureFlag.UnlockViaSDK]: FALSE,
    /* Platform */
    [feature_flag_enum_FeatureFlag.ContentScriptIpcChannelFramework]: FALSE,
    [feature_flag_enum_FeatureFlag.WebAuthnRelatedOrigins]: FALSE,
    [feature_flag_enum_FeatureFlag.PM34410AttachmentUploadProgress]: FALSE,
    /* Innovation */
    [feature_flag_enum_FeatureFlag.ElectronStorageCache]: FALSE,
    /* Desktop */
    [feature_flag_enum_FeatureFlag.DesktopUiMigrationMilestone3]: FALSE,
    [feature_flag_enum_FeatureFlag.DesktopUiMigrationMilestone4]: FALSE,
};
function getFeatureFlagValue(serverConfig, flag) {
    if ((serverConfig === null || serverConfig === void 0 ? void 0 : serverConfig.featureStates) == null || serverConfig.featureStates[flag] == null) {
        return DefaultFeatureFlagValue[flag];
    }
    return serverConfig.featureStates[flag];
}

;// ../../libs/key-management/src/user-asymmetric-key-regeneration/services/default-user-asymmetric-key-regeneration.service.ts
var default_user_asymmetric_key_regeneration_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};




class DefaultUserAsymmetricKeysRegenerationService {
    constructor(keyService, cipherService, userAsymmetricKeysRegenerationApiService, logService, sdkService, apiService, configService, accountCryptographyStateService) {
        this.keyService = keyService;
        this.cipherService = cipherService;
        this.userAsymmetricKeysRegenerationApiService = userAsymmetricKeysRegenerationApiService;
        this.logService = logService;
        this.sdkService = sdkService;
        this.apiService = apiService;
        this.configService = configService;
        this.accountCryptographyStateService = accountCryptographyStateService;
    }
    regenerateIfNeeded(userId) {
        return default_user_asymmetric_key_regeneration_service_awaiter(this, void 0, void 0, function* () {
            try {
                const privateKeyRegenerationFlag = yield this.configService.getFeatureFlag(FeatureFlag.PrivateKeyRegeneration);
                if (privateKeyRegenerationFlag) {
                    const shouldRegenerate = yield this.shouldRegenerate(userId);
                    if (shouldRegenerate) {
                        yield this.regenerateUserPublicKeyEncryptionKeyPair(userId);
                    }
                }
            }
            catch (error) {
                this.logService.error("[UserAsymmetricKeyRegeneration] An error occurred. Skipping regeneration for the user.", error);
            }
        });
    }
    shouldRegenerate(userId) {
        return default_user_asymmetric_key_regeneration_service_awaiter(this, void 0, void 0, function* () {
            const userKey = yield firstValueFrom(this.keyService.userKey$(userId));
            // For SSO logins from untrusted devices, the userKey will not be available, and the private key regeneration process should be skipped.
            // In such cases, regeneration will occur on the following device login flow.
            if (!userKey) {
                this.logService.info("[UserAsymmetricKeyRegeneration] User symmetric key unavailable, skipping regeneration for the user.");
                return false;
            }
            if (userKey.inner().type === EncryptionType.CoseEncrypt0) {
                this.logService.error("[UserAsymmetricKeyRegeneration] Cannot regenerate asymmetric keys for accounts on V2 encryption.");
                return false;
            }
            const userKeyEncryptedPrivateKey = yield firstValueFrom(this.keyService.userEncryptedPrivateKey$(userId));
            let publicKeyResponse = null;
            try {
                publicKeyResponse = yield this.apiService.getUserPublicKey(userId);
            }
            catch (e) {
                if ((e === null || e === void 0 ? void 0 : e.statusCode) !== 404) {
                    throw e;
                }
            }
            // If a user doesn't have a keypair at all, attempt to create one. We have a subset of old users in this state.
            if (!userKeyEncryptedPrivateKey && !publicKeyResponse) {
                this.logService.info("[UserAsymmetricKeyRegeneration] User has no asymmetric keys, attempting to create a new keypair.");
                return true;
            }
            // If the user has one but not the other, something is wrong so log a warning and skip regeneration.
            if (!userKeyEncryptedPrivateKey || !publicKeyResponse) {
                this.logService.warning("[UserAsymmetricKeyRegeneration] User's asymmetric key initialization data is unavailable, skipping regeneration.");
                return false;
            }
            const verificationResponse = yield firstValueFrom(this.sdkService.client$.pipe(map((sdk) => {
                if (sdk === undefined) {
                    throw new Error("SDK is undefined");
                }
                return sdk.crypto().verify_asymmetric_keys({
                    userKey: userKey.keyB64,
                    userPublicKey: publicKeyResponse.publicKey,
                    userKeyEncryptedPrivateKey: userKeyEncryptedPrivateKey,
                });
            })));
            if (verificationResponse.privateKeyDecryptable) {
                if (verificationResponse.validPrivateKey) {
                    // The private key is decryptable and valid. Should not regenerate.
                    return false;
                }
                else {
                    // The private key is decryptable but not valid so we should regenerate it.
                    this.logService.info("[UserAsymmetricKeyRegeneration] User's private key is decryptable but not a valid key, attempting regeneration.");
                    return true;
                }
            }
            // The private isn't decryptable, check to see if we can decrypt something with the userKey.
            const userKeyCanDecrypt = yield this.userKeyCanDecrypt(userKey, userId);
            if (userKeyCanDecrypt) {
                this.logService.info("[UserAsymmetricKeyRegeneration] User Asymmetric Key decryption failure detected, attempting regeneration.");
                return true;
            }
            this.logService.warning("[UserAsymmetricKeyRegeneration] User Asymmetric Key decryption failure detected, but unable to determine User Symmetric Key validity, skipping regeneration.");
            return false;
        });
    }
    regenerateUserPublicKeyEncryptionKeyPair(userId) {
        return default_user_asymmetric_key_regeneration_service_awaiter(this, void 0, void 0, function* () {
            const userKey = yield firstValueFrom(this.keyService.userKey$(userId));
            if (userKey == null) {
                throw new Error("User key not found");
            }
            if (userKey.inner().type !== EncryptionType.AesCbc256_HmacSha256_B64) {
                throw new Error("User key is not V1 encryption type");
            }
            const makeKeyPairResponse = yield firstValueFrom(this.sdkService.client$.pipe(map((sdk) => {
                if (sdk === undefined) {
                    throw new Error("SDK is undefined");
                }
                return sdk.crypto().make_key_pair(userKey.keyB64);
            })));
            try {
                yield this.userAsymmetricKeysRegenerationApiService.regenerateUserAsymmetricKeys(makeKeyPairResponse.userPublicKey, new EncString(makeKeyPairResponse.userKeyEncryptedPrivateKey));
            }
            catch (error) {
                if ((error === null || error === void 0 ? void 0 : error.message) === "Key regeneration not supported for this user.") {
                    this.logService.info("[UserAsymmetricKeyRegeneration] Regeneration not supported for this user at this time.");
                    return false;
                }
                else {
                    this.logService.error("[UserAsymmetricKeyRegeneration] Regeneration error when submitting the request to the server.", error);
                    return false;
                }
            }
            yield this.accountCryptographyStateService.setAccountCryptographicState({
                V1: {
                    private_key: makeKeyPairResponse.userKeyEncryptedPrivateKey,
                },
            }, userId);
            this.logService.info("[UserAsymmetricKeyRegeneration] User's asymmetric keys successfully regenerated.");
            return true;
        });
    }
    userKeyCanDecrypt(userKey, userId) {
        return default_user_asymmetric_key_regeneration_service_awaiter(this, void 0, void 0, function* () {
            const ciphers = yield this.cipherService.getAll(userId);
            const cipher = ciphers.find((cipher) => cipher.organizationId == null);
            if (!cipher) {
                return false;
            }
            try {
                const cipherView = yield cipher.decrypt(userKey);
                if (cipherView.decryptionFailure) {
                    this.logService.error("[UserAsymmetricKeyRegeneration] User Symmetric Key validation error: Cipher decryption failed");
                    return false;
                }
                return true;
            }
            catch (error) {
                this.logService.error("[UserAsymmetricKeyRegeneration] User Symmetric Key validation error.", error);
                return false;
            }
        });
    }
}

;// ../../libs/key-management/src/user-asymmetric-key-regeneration/services/default-user-asymmetric-key-regeneration-api.service.ts
var default_user_asymmetric_key_regeneration_api_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
class DefaultUserAsymmetricKeysRegenerationApiService {
    constructor(apiService) {
        this.apiService = apiService;
    }
    regenerateUserAsymmetricKeys(userPublicKey, userKeyEncryptedUserPrivateKey) {
        return default_user_asymmetric_key_regeneration_api_service_awaiter(this, void 0, void 0, function* () {
            const request = {
                userPublicKey,
                userKeyEncryptedUserPrivateKey,
            };
            yield this.apiService.send("POST", "/accounts/key-management/regenerate-keys", request, true, true);
        });
    }
}

;// ../../libs/key-management/src/user-asymmetric-key-regeneration/index.ts





;// ../../libs/key-management/src/index.ts













;// ../../libs/common/src/key-management/security-state/response/security-state.response.ts
class SecurityStateResponse {
    constructor(response) {
        this.securityState = null;
        if (typeof response !== "object" || response == null) {
            throw new TypeError("Response must be an object");
        }
        if (!("securityState" in response) || !(typeof response.securityState === "string")) {
            throw new TypeError("Response must contain a valid securityState");
        }
        this.securityState = response.securityState;
    }
}

;// ../../libs/common/src/key-management/keys/response/public-key-encryption-key-pair.response.ts

class PublicKeyEncryptionKeyPairResponse {
    constructor(response) {
        this.signedPublicKey = null;
        if (typeof response !== "object" || response == null) {
            throw new TypeError("Response must be an object");
        }
        if (!("publicKey" in response) || typeof response.publicKey !== "string") {
            throw new TypeError("Response must contain a valid publicKey");
        }
        this.publicKey = utils_Utils.fromB64ToArray(response.publicKey);
        if (!("wrappedPrivateKey" in response) || typeof response.wrappedPrivateKey !== "string") {
            throw new TypeError("Response must contain a valid wrappedPrivateKey");
        }
        this.wrappedPrivateKey = response.wrappedPrivateKey;
        if ("signedPublicKey" in response && typeof response.signedPublicKey === "string") {
            this.signedPublicKey = response.signedPublicKey;
        }
        else {
            this.signedPublicKey = null;
        }
    }
}

;// ../../libs/common/src/key-management/keys/response/signature-key-pair.response.ts
class SignatureKeyPairResponse {
    constructor(response) {
        if (typeof response !== "object" || response == null) {
            throw new TypeError("Response must be an object");
        }
        if (!("wrappedSigningKey" in response) || typeof response.wrappedSigningKey !== "string") {
            throw new TypeError("Response must contain a valid wrappedSigningKey");
        }
        this.wrappedSigningKey = response.wrappedSigningKey;
        if (!("verifyingKey" in response) || typeof response.verifyingKey !== "string") {
            throw new TypeError("Response must contain a valid verifyingKey");
        }
        this.verifyingKey = response.verifyingKey;
    }
}

;// ../../libs/common/src/key-management/keys/response/private-keys.response.ts



/**
 * The privately accessible view of an entity (account / org)'s keys.
 * This includes the full key-pairs for public-key encryption and signing, as well as the security state if available.
 */
class PrivateKeysResponseModel {
    constructor(response) {
        this.signatureKeyPair = null;
        this.securityState = null;
        if (typeof response !== "object" || response == null) {
            throw new TypeError("Response must be an object");
        }
        if (!("publicKeyEncryptionKeyPair" in response) ||
            typeof response.publicKeyEncryptionKeyPair !== "object") {
            throw new TypeError("Response must contain a valid publicKeyEncryptionKeyPair");
        }
        this.publicKeyEncryptionKeyPair = new PublicKeyEncryptionKeyPairResponse(response.publicKeyEncryptionKeyPair);
        if ("signatureKeyPair" in response &&
            typeof response.signatureKeyPair === "object" &&
            response.signatureKeyPair != null) {
            this.signatureKeyPair = new SignatureKeyPairResponse(response.signatureKeyPair);
        }
        if ("securityState" in response &&
            typeof response.securityState === "object" &&
            response.securityState != null) {
            this.securityState = new SecurityStateResponse(response.securityState);
        }
        if ((this.signatureKeyPair !== null && this.securityState === null) ||
            (this.signatureKeyPair === null && this.securityState !== null)) {
            throw new TypeError("Both signatureKeyPair and securityState must be present or absent together");
        }
    }
    toWrappedAccountCryptographicState() {
        if (this.signatureKeyPair === null && this.securityState === null) {
            // V1 user
            return {
                V1: {
                    private_key: this.publicKeyEncryptionKeyPair.wrappedPrivateKey,
                },
            };
        }
        else if (this.signatureKeyPair !== null && this.securityState !== null) {
            // V2 user
            return {
                V2: {
                    private_key: this.publicKeyEncryptionKeyPair.wrappedPrivateKey,
                    signing_key: this.signatureKeyPair.wrappedSigningKey,
                    signed_public_key: this.publicKeyEncryptionKeyPair.signedPublicKey,
                    security_state: this.securityState.securityState,
                },
            };
        }
        else {
            throw new Error("Both signatureKeyPair and securityState must be present or absent together");
        }
    }
    isV2Encryption() {
        return this.signatureKeyPair !== null && this.securityState !== null;
    }
}

;// ../../libs/common/src/auth/models/response/master-password-policy.response.ts

class MasterPasswordPolicyResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.minComplexity = this.getResponseProperty("MinComplexity");
        this.minLength = this.getResponseProperty("MinLength");
        this.requireUpper = this.getResponseProperty("RequireUpper");
        this.requireLower = this.getResponseProperty("RequireLower");
        this.requireNumbers = this.getResponseProperty("RequireNumbers");
        this.requireSpecial = this.getResponseProperty("RequireSpecial");
        this.enforceOnLogin = this.getResponseProperty("EnforceOnLogin");
    }
}

;// ../../libs/common/src/key-management/models/response/kdf-config.response.ts
// eslint-disable-next-line no-restricted-imports


class KdfConfigResponse extends BaseResponse {
    constructor(response) {
        super(response);
        const kdfType = this.getResponseProperty("KdfType");
        if (kdfType == null || typeof kdfType !== "number") {
            throw new Error("KDF config response does not contain a valid KDF type");
        }
        this.kdfType = kdfType;
        const iterations = this.getResponseProperty("Iterations");
        if (iterations == null || typeof iterations !== "number") {
            throw new Error("KDF config response does not contain a valid number of iterations");
        }
        this.iterations = iterations;
        if (this.kdfType === kdf_type_enum_KdfType.Argon2id) {
            const memory = this.getResponseProperty("Memory");
            if (memory == null || typeof memory !== "number") {
                throw new Error("KDF config response does not contain a valid memory size for Argon2id");
            }
            const parallelism = this.getResponseProperty("Parallelism");
            if (parallelism == null || typeof parallelism !== "number") {
                throw new Error("KDF config response does not contain a valid parallelism for Argon2id");
            }
            this.memory = memory;
            this.parallelism = parallelism;
        }
    }
    toKdfConfig() {
        switch (this.kdfType) {
            case kdf_type_enum_KdfType.Argon2id:
                return new Argon2KdfConfig(this.iterations, this.memory, this.parallelism);
            case kdf_type_enum_KdfType.PBKDF2_SHA256:
                return new PBKDF2KdfConfig(this.iterations);
        }
    }
}

;// ../../libs/common/src/key-management/master-password/types/master-password.types.ts
// eslint-disable-next-line no-restricted-imports

/**
 * Encapsulates the data needed to unlock a vault using a master password.
 * It contains the masterKeyWrappedUserKey along with the KDF settings and salt used to derive the master key.
 * It is currently backwards compatible to master-key based unlock, but this will not be the case in the future.
 * Features relating to master-password-based unlock should use this abstraction.
 */
class MasterPasswordUnlockData {
    constructor(salt, kdf, masterKeyWrappedUserKey) {
        this.salt = salt;
        this.kdf = kdf;
        this.masterKeyWrappedUserKey = masterKeyWrappedUserKey;
    }
    static fromSdk(sdkData) {
        return new MasterPasswordUnlockData(sdkData.salt, fromSdkKdfConfig(sdkData.kdf), sdkData.masterKeyWrappedUserKey);
    }
    toSdk() {
        return {
            salt: this.salt,
            kdf: this.kdf.toSdkConfig(),
            masterKeyWrappedUserKey: this.masterKeyWrappedUserKey,
        };
    }
    toJSON() {
        return {
            salt: this.salt,
            kdf: this.kdf,
            masterKeyWrappedUserKey: this.masterKeyWrappedUserKey,
        };
    }
    static fromJSON(obj) {
        if (obj == null) {
            return null;
        }
        return new MasterPasswordUnlockData(obj.salt, obj.kdf.kdfType === kdf_type_enum_KdfType.PBKDF2_SHA256
            ? PBKDF2KdfConfig.fromJSON(obj.kdf)
            : Argon2KdfConfig.fromJSON(obj.kdf), obj.masterKeyWrappedUserKey);
    }
}
function fromSdkAuthenticationData(sdkData) {
    return {
        salt: sdkData.salt,
        kdf: fromSdkKdfConfig(sdkData.kdf),
        masterPasswordAuthenticationHash: sdkData.masterPasswordAuthenticationHash,
    };
}

;// ../../libs/common/src/key-management/master-password/models/response/master-password-unlock.response.ts



class MasterPasswordUnlockResponse extends BaseResponse {
    constructor(response) {
        super(response);
        const salt = this.getResponseProperty("Salt");
        if (salt == null || typeof salt !== "string") {
            throw new Error("MasterPasswordUnlockResponse does not contain a valid salt");
        }
        this.salt = salt;
        this.kdf = new KdfConfigResponse(this.getResponseProperty("Kdf"));
        // Note: MasterKeyEncryptedUserKey and masterKeyWrappedUserKey are the same thing, and
        // used inconsistently in the codebase
        const masterKeyWrappedUserKey = this.getResponseProperty("MasterKeyEncryptedUserKey");
        if (masterKeyWrappedUserKey == null || typeof masterKeyWrappedUserKey !== "string") {
            throw new Error("MasterPasswordUnlockResponse does not contain a valid master key encrypted user key");
        }
        this.masterKeyWrappedUserKey = masterKeyWrappedUserKey;
    }
    toMasterPasswordUnlockData() {
        return new MasterPasswordUnlockData(this.salt, this.kdf.toKdfConfig(), this.masterKeyWrappedUserKey);
    }
}

;// ../../libs/common/src/auth/models/response/user-decryption-options/key-connector-user-decryption-option.response.ts

class KeyConnectorUserDecryptionOptionResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.keyConnectorUrl = this.getResponseProperty("KeyConnectorUrl");
    }
}

;// ../../libs/common/src/auth/models/response/user-decryption-options/trusted-device-user-decryption-option.response.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


class TrustedDeviceUserDecryptionOptionResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.hasAdminApproval = this.getResponseProperty("HasAdminApproval");
        this.hasLoginApprovingDevice = this.getResponseProperty("HasLoginApprovingDevice");
        this.hasManageResetPasswordPermission = this.getResponseProperty("HasManageResetPasswordPermission");
        this.isTdeOffboarding = this.getResponseProperty("IsTdeOffboarding");
        if (response.EncryptedPrivateKey) {
            this.encryptedPrivateKey = new enc_string_EncString(this.getResponseProperty("EncryptedPrivateKey"));
        }
        if (response.EncryptedUserKey) {
            this.encryptedUserKey = new enc_string_EncString(this.getResponseProperty("EncryptedUserKey"));
        }
    }
}

;// ../../libs/common/src/auth/models/response/user-decryption-options/webauthn-prf-decryption-option.response.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


class WebAuthnPrfDecryptionOptionResponse extends BaseResponse {
    constructor(response) {
        super(response);
        const encPrivateKey = this.getResponseProperty("EncryptedPrivateKey");
        if (encPrivateKey) {
            this.encryptedPrivateKey = new enc_string_EncString(encPrivateKey);
        }
        const encUserKey = this.getResponseProperty("EncryptedUserKey");
        if (encUserKey) {
            this.encryptedUserKey = new enc_string_EncString(encUserKey);
        }
        this.credentialId = this.getResponseProperty("CredentialId");
        this.transports = this.getResponseProperty("Transports") || [];
    }
}

;// ../../libs/common/src/auth/models/response/user-decryption-options/user-decryption-options.response.ts





class UserDecryptionOptionsResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.hasMasterPassword = this.getResponseProperty("HasMasterPassword");
        const masterPasswordUnlock = this.getResponseProperty("MasterPasswordUnlock");
        if (masterPasswordUnlock != null && typeof masterPasswordUnlock === "object") {
            this.masterPasswordUnlock = new MasterPasswordUnlockResponse(masterPasswordUnlock);
        }
        if (response.TrustedDeviceOption) {
            this.trustedDeviceOption = new TrustedDeviceUserDecryptionOptionResponse(this.getResponseProperty("TrustedDeviceOption"));
        }
        if (response.KeyConnectorOption) {
            this.keyConnectorOption = new KeyConnectorUserDecryptionOptionResponse(this.getResponseProperty("KeyConnectorOption"));
        }
        if (response.WebAuthnPrfOption) {
            this.webAuthnPrfOption = new WebAuthnPrfDecryptionOptionResponse(this.getResponseProperty("WebAuthnPrfOption"));
        }
    }
}

;// ../../libs/common/src/auth/models/response/identity-token.response.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop.
// eslint-disable-next-line no-restricted-imports






class IdentityTokenResponse extends BaseResponse {
    constructor(response) {
        super(response);
        // TODO: https://bitwarden.atlassian.net/browse/PM-30124 - Rename to just accountKeys
        this.accountKeysResponseModel = null;
        const accessToken = this.getResponseProperty("access_token");
        if (accessToken == null || typeof accessToken !== "string") {
            throw new Error("Identity response does not contain a valid access token");
        }
        const tokenType = this.getResponseProperty("token_type");
        if (tokenType == null || typeof tokenType !== "string") {
            throw new Error("Identity response does not contain a valid token type");
        }
        this.accessToken = accessToken;
        this.tokenType = tokenType;
        const expiresIn = this.getResponseProperty("expires_in");
        if (expiresIn != null && typeof expiresIn === "number") {
            this.expiresIn = expiresIn;
        }
        const refreshToken = this.getResponseProperty("refresh_token");
        if (refreshToken != null && typeof refreshToken === "string") {
            this.refreshToken = refreshToken;
        }
        this.privateKey = this.getResponseProperty("PrivateKey");
        if (this.getResponseProperty("AccountKeys") != null) {
            this.accountKeysResponseModel = new PrivateKeysResponseModel(this.getResponseProperty("AccountKeys"));
        }
        const key = this.getResponseProperty("Key");
        if (key) {
            this.key = new enc_string_EncString(key);
        }
        this.twoFactorToken = this.getResponseProperty("TwoFactorToken");
        const kdf = this.getResponseProperty("Kdf");
        const kdfIterations = this.getResponseProperty("KdfIterations");
        const kdfMemory = this.getResponseProperty("KdfMemory");
        const kdfParallelism = this.getResponseProperty("KdfParallelism");
        switch (kdf) {
            case kdf_type_enum_KdfType.PBKDF2_SHA256:
                this.kdfConfig = new PBKDF2KdfConfig(kdfIterations);
                break;
            case kdf_type_enum_KdfType.Argon2id:
                this.kdfConfig = new Argon2KdfConfig(kdfIterations, kdfMemory, kdfParallelism);
                break;
            default:
                throw new Error("kdf is required on IdentityTokenResponse");
        }
        this.forcePasswordReset = this.getResponseProperty("ForcePasswordReset");
        this.apiUseKeyConnector = this.getResponseProperty("ApiUseKeyConnector");
        this.masterPasswordPolicy = new MasterPasswordPolicyResponse(this.getResponseProperty("MasterPasswordPolicy"));
        const userDecryptionOptions = this.getResponseProperty("UserDecryptionOptions");
        if (userDecryptionOptions != null && typeof userDecryptionOptions === "object") {
            this.userDecryptionOptions = new UserDecryptionOptionsResponse(userDecryptionOptions);
        }
    }
    hasMasterKeyEncryptedUserKey() {
        return Boolean(this.key);
    }
    canUnlockWithKeyConnector() {
        var _a;
        return ((_a = this.userDecryptionOptions) === null || _a === void 0 ? void 0 : _a.keyConnectorOption) != null;
    }
    intoKeyConnectorUnlockData() {
        if (!this.canUnlockWithKeyConnector()) {
            throw new Error("Identity token response cannot be used for key connector unlock");
        }
        return {
            url: this.userDecryptionOptions.keyConnectorOption.keyConnectorUrl,
            keyConnectorKeyWrappedUserKey: this.key.toSdk(),
        };
    }
}

;// ../../libs/common/src/auth/models/response/identity-two-factor.response.ts


class IdentityTwoFactorResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.twoFactorProviders = this.getResponseProperty("TwoFactorProviders");
        this.twoFactorProviders2 = this.getResponseProperty("TwoFactorProviders2");
        this.masterPasswordPolicy = new MasterPasswordPolicyResponse(this.getResponseProperty("MasterPasswordPolicy"));
        this.ssoEmail2faSessionToken = this.getResponseProperty("SsoEmail2faSessionToken");
        this.email = this.getResponseProperty("Email");
    }
}

;// ../../libs/auth/src/common/login-strategies/login.strategy.ts
var login_strategy_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};











class LoginStrategyData {
}
class LoginStrategy {
    constructor(accountService, masterPasswordService, keyService, encryptService, apiService, tokenService, appIdService, platformUtilsService, messagingService, logService, stateService, twoFactorService, userDecryptionOptionsService, billingAccountProfileStateService, vaultTimeoutSettingsService, KdfConfigService, environmentService, configService, accountCryptographicStateService) {
        this.accountService = accountService;
        this.masterPasswordService = masterPasswordService;
        this.keyService = keyService;
        this.encryptService = encryptService;
        this.apiService = apiService;
        this.tokenService = tokenService;
        this.appIdService = appIdService;
        this.platformUtilsService = platformUtilsService;
        this.messagingService = messagingService;
        this.logService = logService;
        this.stateService = stateService;
        this.twoFactorService = twoFactorService;
        this.userDecryptionOptionsService = userDecryptionOptionsService;
        this.billingAccountProfileStateService = billingAccountProfileStateService;
        this.vaultTimeoutSettingsService = vaultTimeoutSettingsService;
        this.KdfConfigService = KdfConfigService;
        this.environmentService = environmentService;
        this.configService = configService;
        this.accountCryptographicStateService = accountCryptographicStateService;
        this.sessionTimeoutSubject = new external_rxjs_namespaceObject.BehaviorSubject(false);
        this.sessionTimeout$ = this.sessionTimeoutSubject.asObservable();
    }
    logInTwoFactor(twoFactor) {
        return login_strategy_awaiter(this, void 0, void 0, function* () {
            var _a;
            const data = this.cache.value;
            if (!data.tokenRequest) {
                throw new Error("Token request is undefined");
            }
            data.tokenRequest.setTwoFactor(twoFactor);
            this.cache.next(data);
            const [authResult] = yield this.startLogIn();
            // There is an import cycle between PasswordLoginStrategyData and LoginStrategy, which means this cast is necessary, which is solved by extracting the data classes.
            authResult.masterPassword = (_a = this.cache.value["masterPassword"]) !== null && _a !== void 0 ? _a : null;
            return authResult;
        });
    }
    startLogIn() {
        return login_strategy_awaiter(this, void 0, void 0, function* () {
            yield this.twoFactorService.clearSelectedProvider();
            const tokenRequest = this.cache.value.tokenRequest;
            if (!tokenRequest) {
                throw new Error("Token request is undefined");
            }
            const response = yield this.apiService.postIdentityToken(tokenRequest);
            if (response instanceof IdentityTwoFactorResponse) {
                return [yield this.processTwoFactorResponse(response), response];
            }
            else if (response instanceof IdentityTokenResponse) {
                return [yield this.processTokenResponse(response), response];
            }
            else if (response instanceof IdentityDeviceVerificationResponse) {
                return [yield this.processDeviceVerificationResponse(response), response];
            }
            else if (response instanceof IdentitySsoRequiredResponse) {
                return [yield this.processSsoRequiredResponse(response), response];
            }
            throw new Error("Invalid response object.");
        });
    }
    buildDeviceRequest() {
        return login_strategy_awaiter(this, void 0, void 0, function* () {
            const appId = yield this.appIdService.getAppId();
            return new DeviceRequest(appId, this.platformUtilsService);
        });
    }
    /**
     * Builds the TokenTwoFactorRequest to be used within other login strategies token requests
     * to the server.
     * If the user provided a 2FA token in an already created TokenTwoFactorRequest, it will be used.
     * If not, and the user has previously remembered a 2FA token, it will be used.
     * If neither of these are true, an empty TokenTwoFactorRequest will be returned.
     * @param userProvidedTwoFactor - optional - The 2FA token request provided by the caller
     * @param email - optional - ensure that email is provided for any login strategies that support remember 2FA functionality
     * @returns a promise which resolves to a TokenTwoFactorRequest to be sent to the server
     */
    buildTwoFactor(userProvidedTwoFactor, email) {
        return login_strategy_awaiter(this, void 0, void 0, function* () {
            if (userProvidedTwoFactor != null) {
                return userProvidedTwoFactor;
            }
            if (email) {
                const storedTwoFactorToken = yield this.tokenService.getTwoFactorToken(email);
                if (storedTwoFactorToken != null) {
                    return new TokenTwoFactorRequest(TwoFactorProviderType.Remember, storedTwoFactorToken, false);
                }
            }
            return new TokenTwoFactorRequest();
        });
    }
    /**
     * Initializes the account with information from the IdTokenResponse after successful login.
     * It also sets the access token and refresh token in the token service.
     *
     * @param {IdentityTokenResponse} tokenResponse - The response from the server containing the identity token.
     * @returns {Promise<UserId>} - A promise that resolves the the UserId when the account information has been successfully saved.
     */
    saveAccountInformation(tokenResponse) {
        return login_strategy_awaiter(this, void 0, void 0, function* () {
            var _a, _b, _c, _d;
            const accountInformation = yield this.tokenService.decodeAccessToken(tokenResponse.accessToken);
            const userId = accountInformation.sub;
            yield this.accountService.addAccount(userId, {
                name: accountInformation.name,
                email: (_a = accountInformation.email) !== null && _a !== void 0 ? _a : "",
                emailVerified: (_b = accountInformation.email_verified) !== null && _b !== void 0 ? _b : false,
                creationDate: undefined, // We don't get a creation date in the token. See https://bitwarden.atlassian.net/browse/PM-29551 for consolidation plans.
            });
            // User env must be seeded from currently set env before switching to the account
            // to avoid any incorrect emissions of the global default env.
            yield this.environmentService.seedUserEnvironment(userId);
            yield this.accountService.switchAccount(userId);
            yield this.verifyAccountAdded(userId);
            // We must set user decryption options before retrieving vault timeout settings
            // as the user decryption options help determine the available timeout actions.
            yield this.userDecryptionOptionsService.setUserDecryptionOptionsById(userId, UserDecryptionOptions.fromIdentityTokenResponse(tokenResponse));
            if (((_c = tokenResponse.userDecryptionOptions) === null || _c === void 0 ? void 0 : _c.masterPasswordUnlock) != null) {
                const masterPasswordUnlockData = tokenResponse.userDecryptionOptions.masterPasswordUnlock.toMasterPasswordUnlockData();
                yield this.masterPasswordService.setMasterPasswordUnlockData(masterPasswordUnlockData, userId);
            }
            const vaultTimeoutAction = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.vaultTimeoutSettingsService.getVaultTimeoutActionByUserId$(userId));
            const vaultTimeout = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.vaultTimeoutSettingsService.getVaultTimeoutByUserId$(userId));
            // User id will be derived from the access token.
            yield this.tokenService.setTokens(tokenResponse.accessToken, vaultTimeoutAction, vaultTimeout, tokenResponse.refreshToken);
            yield this.KdfConfigService.setKdfConfig(userId, tokenResponse.kdfConfig);
            yield this.billingAccountProfileStateService.setHasPremium((_d = accountInformation.premium) !== null && _d !== void 0 ? _d : false, false, userId);
            return userId;
        });
    }
    processTokenResponse(response) {
        return login_strategy_awaiter(this, void 0, void 0, function* () {
            var _a;
            const result = new AuthResult();
            // Encryption key migration of legacy users (with no userkey) is not supported anymore
            if (this.encryptionKeyMigrationRequired(response)) {
                result.requiresEncryptionKeyMigration = true;
                return result;
            }
            // Must come before setting keys, user key needs email to update additional keys.
            const userId = yield this.saveAccountInformation(response);
            result.userId = userId;
            if (response.twoFactorToken != null) {
                // note: we can read email from access token b/c it was saved in saveAccountInformation
                const userEmail = yield this.tokenService.getEmail();
                yield this.tokenService.setTwoFactorToken(userEmail, response.twoFactorToken);
            }
            yield this.setMasterKey(response, userId);
            yield this.setAccountCryptographicState(response, userId);
            yield this.setUserKey(response, userId);
            // This needs to run after the keys are set because it checks for the existence of the encrypted private key
            yield this.processForceSetPasswordReason(response.forcePasswordReset, userId);
            this.messagingService.send("loggedIn");
            // There is an import cycle between PasswordLoginStrategyData and LoginStrategy, which means this cast is necessary, which is solved by extracting the data classes.
            // TODO: https://bitwarden.atlassian.net/browse/PM-27573
            result.masterPassword = (_a = this.cache.value["masterPassword"]) !== null && _a !== void 0 ? _a : null;
            return result;
        });
    }
    // Old accounts used master key for encryption. We are forcing migrations but only need to
    // check on password logins
    encryptionKeyMigrationRequired(response) {
        return false;
    }
    /**
     * Checks if adminForcePasswordReset is true and sets the ForceSetPasswordReason.AdminForcePasswordReset flag in the master password service.
     * @param adminForcePasswordReset - The admin force password reset flag
     * @param userId - The user ID
     * @returns a promise that resolves to a boolean indicating whether the admin force password reset flag was set
     */
    processForceSetPasswordReason(adminForcePasswordReset, userId) {
        return login_strategy_awaiter(this, void 0, void 0, function* () {
            if (!adminForcePasswordReset) {
                return false;
            }
            // set the flag in the master password service so we know when we reach the auth guard
            // that we need to guide them properly to admin password reset.
            yield this.masterPasswordService.setForceSetPasswordReason(ForceSetPasswordReason.AdminForcePasswordReset, userId);
            return true;
        });
    }
    /**
     * Handles the response from the server when a 2FA is required.
     * It clears any existing 2FA token, as it's no longer valid, and sets up the necessary data for the 2FA process.
     *
     * @param {IdentityTwoFactorResponse} response - The response from the server indicating that 2FA is required.
     * @returns {Promise<AuthResult>} - A promise that resolves to an AuthResult object
     */
    processTwoFactorResponse(response) {
        return login_strategy_awaiter(this, void 0, void 0, function* () {
            var _a;
            // If we get a 2FA required response, then we should clear the 2FA token
            // just in case as it is no longer valid.
            yield this.clearTwoFactorToken();
            const result = new AuthResult();
            result.twoFactorProviders = response.twoFactorProviders2;
            yield this.twoFactorService.setProviders(response);
            result.ssoEmail2FaSessionToken = response.ssoEmail2faSessionToken;
            result.email = (_a = response.email) !== null && _a !== void 0 ? _a : "";
            return result;
        });
    }
    /**
     * Clears the 2FA token from the token service using the user's email if it exists
     */
    clearTwoFactorToken() {
        return login_strategy_awaiter(this, void 0, void 0, function* () {
            const email = this.cache.value.userEnteredEmail;
            if (email) {
                yield this.tokenService.clearTwoFactorToken(email);
            }
        });
    }
    /**
     * Verifies that the active account is set after initialization.
     * Note: In browser there is a slight delay between when active account emits in background,
     * and when it emits in foreground. We're giving the foreground 1 second to catch up.
     * If nothing is emitted, we throw an error.
     */
    verifyAccountAdded(expectedUserId) {
        return login_strategy_awaiter(this, void 0, void 0, function* () {
            yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.filter)((account) => (account === null || account === void 0 ? void 0 : account.id) === expectedUserId), (0,external_rxjs_namespaceObject.timeout)({
                first: 1000,
                with: () => {
                    throw new Error("Expected user never made active user after initialization.");
                },
            })));
        });
    }
    /**
     * Handles the response from the server when a device verification is required.
     * It sets the requiresDeviceVerification flag to true.
     *
     * @param {IdentityDeviceVerificationResponse} response - The response from the server indicating that device verification is required.
     * @returns {Promise<AuthResult>} - A promise that resolves to an AuthResult object
     */
    processDeviceVerificationResponse(response) {
        return login_strategy_awaiter(this, void 0, void 0, function* () {
            const result = new AuthResult();
            result.requiresDeviceVerification = true;
            return result;
        });
    }
    /**
     * Handles the response from the server when a SSO Authentication is required.
     * It hydrates the AuthResult with the SSO organization identifier.
     *
     * @param {IdentitySsoRequiredResponse} response - The response from the server indicating that SSO is required.
     * @returns {Promise<AuthResult>} - A promise that resolves to an AuthResult object
     */
    processSsoRequiredResponse(response) {
        return login_strategy_awaiter(this, void 0, void 0, function* () {
            const result = new AuthResult();
            result.ssoOrganizationIdentifier = response.ssoOrganizationIdentifier;
            return result;
        });
    }
}

;// ../../libs/auth/src/common/login-strategies/auth-request-login.strategy.ts
var auth_request_login_strategy_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore




class AuthRequestLoginStrategyData {
    static fromJSON(obj) {
        const data = Object.assign(new AuthRequestLoginStrategyData(), obj, {
            tokenRequest: PasswordTokenRequest.fromJSON(obj.tokenRequest),
            authRequestCredentials: AuthRequestLoginCredentials.fromJSON(obj.authRequestCredentials),
        });
        return data;
    }
}
class AuthRequestLoginStrategy extends LoginStrategy {
    constructor(data, deviceTrustService, ...sharedDeps) {
        super(...sharedDeps);
        this.deviceTrustService = deviceTrustService;
        this.cache = new external_rxjs_namespaceObject.BehaviorSubject(data);
        this.email$ = this.cache.pipe((0,external_rxjs_namespaceObject.map)((data) => data.tokenRequest.email));
        this.accessCode$ = this.cache.pipe((0,external_rxjs_namespaceObject.map)((data) => data.authRequestCredentials.accessCode));
        this.authRequestId$ = this.cache.pipe((0,external_rxjs_namespaceObject.map)((data) => data.authRequestCredentials.authRequestId));
    }
    logIn(credentials) {
        return auth_request_login_strategy_awaiter(this, void 0, void 0, function* () {
            const data = new AuthRequestLoginStrategyData();
            data.tokenRequest = new PasswordTokenRequest(credentials.email, credentials.accessCode, yield this.buildTwoFactor(credentials.twoFactor, credentials.email), yield this.buildDeviceRequest());
            data.tokenRequest.setAuthRequestAccessCode(credentials.authRequestId);
            data.authRequestCredentials = credentials;
            this.cache.next(data);
            const [authResult] = yield this.startLogIn();
            return authResult;
        });
    }
    logInTwoFactor(twoFactor) {
        const _super = Object.create(null, {
            logInTwoFactor: { get: () => super.logInTwoFactor }
        });
        return auth_request_login_strategy_awaiter(this, void 0, void 0, function* () {
            const data = this.cache.value;
            this.cache.next(data);
            return _super.logInTwoFactor.call(this, twoFactor);
        });
    }
    setMasterKey(response, userId) {
        return auth_request_login_strategy_awaiter(this, void 0, void 0, function* () {
            // This login strategy does not use a master key
        });
    }
    setUserKey(response, userId) {
        return auth_request_login_strategy_awaiter(this, void 0, void 0, function* () {
            const authRequestCredentials = this.cache.value.authRequestCredentials;
            // User now may or may not have a master password
            // but set the master key encrypted user key if it exists regardless
            if (response.key) {
                yield this.masterPasswordService.setMasterKeyEncryptedUserKey(response.key, userId);
            }
            if (authRequestCredentials.decryptedUserKey) {
                yield this.keyService.setUserKey(authRequestCredentials.decryptedUserKey, userId);
            }
            else {
                yield this.trySetUserKeyWithMasterKey(userId);
                // Establish trust if required after setting user key
                yield this.deviceTrustService.trustDeviceIfRequired(userId);
            }
        });
    }
    trySetUserKeyWithMasterKey(userId) {
        return auth_request_login_strategy_awaiter(this, void 0, void 0, function* () {
            const masterKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.masterPasswordService.masterKey$(userId));
            if (masterKey) {
                const userKey = yield this.masterPasswordService.decryptUserKeyWithMasterKey(masterKey, userId);
                yield this.keyService.setUserKey(userKey, userId);
            }
        });
    }
    setAccountCryptographicState(response, userId) {
        return auth_request_login_strategy_awaiter(this, void 0, void 0, function* () {
            yield this.accountCryptographicStateService.setAccountCryptographicState(response.accountKeysResponseModel.toWrappedAccountCryptographicState(), userId);
        });
    }
    exportCache() {
        return {
            authRequest: this.cache.value,
        };
    }
}

;// ../../libs/auth/src/common/login-strategies/password-login.strategy.ts
var password_login_strategy_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore










class PasswordLoginStrategyData {
    constructor() {
        /** Whether unlock service should be used for this login flow. */
        this.unlockServiceForPasswordLogin = false;
        /**
         * Tracks if the user needs to update their password due to
         * a password that does not meet an organization's master password policy.
         */
        this.forcePasswordResetReason = ForceSetPasswordReason.None;
    }
    static fromJSON(obj) {
        const data = Object.assign(new PasswordLoginStrategyData(), obj, {
            tokenRequest: PasswordTokenRequest.fromJSON(obj.tokenRequest),
            masterKey: SymmetricCryptoKey.fromJSON(obj.masterKey),
        });
        return data;
    }
}
class PasswordLoginStrategy extends LoginStrategy {
    constructor(data, passwordStrengthService, policyService, passwordPreloginService, unlockService, ...sharedDeps) {
        super(...sharedDeps);
        this.passwordStrengthService = passwordStrengthService;
        this.policyService = policyService;
        this.passwordPreloginService = passwordPreloginService;
        this.unlockService = unlockService;
        this.cache = new external_rxjs_namespaceObject.BehaviorSubject(data);
        this.email$ = this.cache.pipe((0,external_rxjs_namespaceObject.map)((state) => state.tokenRequest.email));
        this.serverMasterKeyHash$ = this.cache.pipe((0,external_rxjs_namespaceObject.map)((state) => state.tokenRequest.masterPasswordHash));
    }
    logIn(credentials) {
        return password_login_strategy_awaiter(this, void 0, void 0, function* () {
            const unlockServiceForPasswordLogin = yield this.configService.getFeatureFlag(feature_flag_enum_FeatureFlag.UseUnlockServiceForPasswordLogin);
            const { email, masterPassword, twoFactor, preFetchedPreloginData } = credentials;
            const data = new PasswordLoginStrategyData();
            data.masterKey = yield this.makePasswordPreloginMasterKey(masterPassword, email, preFetchedPreloginData);
            this.passwordPreloginService.clearCache();
            data.masterPassword = masterPassword;
            data.unlockServiceForPasswordLogin = unlockServiceForPasswordLogin;
            data.userEnteredEmail = email;
            // Hash the password early (before authentication) so we don't persist it in memory in plaintext
            const serverMasterKeyHash = yield this.keyService.hashMasterKey(masterPassword, data.masterKey);
            data.tokenRequest = new PasswordTokenRequest(email, serverMasterKeyHash, yield this.buildTwoFactor(twoFactor, email), yield this.buildDeviceRequest());
            this.cache.next(data);
            const [authResult, identityResponse] = yield this.startLogIn();
            yield this.evaluateMasterPasswordIfRequired(identityResponse, credentials, authResult);
            return authResult;
        });
    }
    logInTwoFactor(twoFactor) {
        const _super = Object.create(null, {
            logInTwoFactor: { get: () => super.logInTwoFactor }
        });
        return password_login_strategy_awaiter(this, void 0, void 0, function* () {
            const result = yield _super.logInTwoFactor.call(this, twoFactor);
            return result;
        });
    }
    setMasterKey(response, userId) {
        return password_login_strategy_awaiter(this, void 0, void 0, function* () {
            if (!this.cache.value.unlockServiceForPasswordLogin) {
                const { masterKey } = this.cache.value;
                yield this.masterPasswordService.setMasterKey(masterKey, userId);
            }
        });
    }
    setUserKey(response, userId) {
        return password_login_strategy_awaiter(this, void 0, void 0, function* () {
            if (this.cache.value.unlockServiceForPasswordLogin) {
                yield this.unlockService.unlockWithMasterPassword(userId, this.cache.value.masterPassword);
            }
            else {
                // If migration is required, we won't have a user key to set yet.
                if (this.encryptionKeyMigrationRequired(response)) {
                    return;
                }
                yield this.masterPasswordService.setMasterKeyEncryptedUserKey(response.key, userId);
                // Warning: State is accessed right after state is set. This could lead to a race condition
                // in some cases where decryptUserKeyWithMasterKey will get a null encrypted user-key!!
                // https://github.com/bitwarden/clients/tree/afc45ee0c8fc823301bb361b0dcac581eb0aff0c/libs/state#updating-state-with-update
                const masterKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.masterPasswordService.masterKey$(userId));
                if (masterKey) {
                    const userKey = yield this.masterPasswordService.decryptUserKeyWithMasterKey(masterKey, userId);
                    yield this.keyService.setUserKey(userKey, userId);
                }
            }
        });
    }
    setAccountCryptographicState(response, userId) {
        return password_login_strategy_awaiter(this, void 0, void 0, function* () {
            yield this.accountCryptographicStateService.setAccountCryptographicState(response.accountKeysResponseModel.toWrappedAccountCryptographicState(), userId);
        });
    }
    encryptionKeyMigrationRequired(response) {
        return !response.key;
    }
    makePasswordPreloginMasterKey(masterPassword, email, preFetchedPreloginData) {
        return password_login_strategy_awaiter(this, void 0, void 0, function* () {
            // if we have prefetched prelogin data, use it
            if (preFetchedPreloginData) {
                return this.keyService.makeMasterKey(masterPassword, email, preFetchedPreloginData.kdfConfig);
            }
            // No prefetched data — fetch now. PasswordPreloginData.fromResponse validates the KDF config.
            const preloginData = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.passwordPreloginService.getPreloginData$(email));
            if (!preloginData) {
                throw new Error("KDF config is required");
            }
            return this.keyService.makeMasterKey(masterPassword, email, preloginData.kdfConfig);
        });
    }
    evaluateMasterPasswordIfRequired(identityResponse, credentials, authResult) {
        return password_login_strategy_awaiter(this, void 0, void 0, function* () {
            // TODO: PM-21084 - investigate if we should be sending down masterPasswordPolicy on the
            // IdentityDeviceVerificationResponse like we do for the IdentityTwoFactorResponse
            // If the response is a device verification response, we don't need to evaluate the password
            // If SSO is required, we also do not evaluate the password here, since the user needs to first
            // authenticate with their SSO IdP Provider
            if (identityResponse instanceof IdentityDeviceVerificationResponse ||
                identityResponse instanceof IdentitySsoRequiredResponse) {
                return;
            }
            // The identity result can contain master password policies for the user's organizations.
            // Get the master password policy options from both the org invite and the identity response.
            const masterPasswordPolicyOptions = this.policyService.combineMasterPasswordPolicyOptions(credentials.masterPasswordPoliciesFromOrgInvite, this.getMasterPasswordPolicyOptionsFromResponse(identityResponse));
            // We deliberately do not check enforceOnLogin as existing users who are logging
            // in after getting an org invite should always be forced to set a password that
            // meets the org's policy. Org Invite -> Registration also works this way for
            // new BW users as well.
            if (!credentials.masterPasswordPoliciesFromOrgInvite &&
                !(masterPasswordPolicyOptions === null || masterPasswordPolicyOptions === void 0 ? void 0 : masterPasswordPolicyOptions.enforceOnLogin)) {
                return;
            }
            // If there is a policy active, evaluate the supplied password before its no longer in memory
            const meetsRequirements = this.evaluateMasterPassword(credentials, masterPasswordPolicyOptions);
            if (meetsRequirements) {
                return;
            }
            if (identityResponse instanceof IdentityTwoFactorResponse) {
                // Save the flag to this strategy for use in 2fa as the master password is about to pass out of scope
                this.cache.next(Object.assign(Object.assign({}, this.cache.value), { forcePasswordResetReason: ForceSetPasswordReason.WeakMasterPassword }));
                return;
            }
            // Authentication was successful, save the force update password options with the state service
            // if there isn't already a reason set (this would only be AdminForcePasswordReset as that can be set server side
            // and would have already been processed in the base login strategy processForceSetPasswordReason method)
            // Note: masterPasswordService.setForceSetPasswordReason will not allow overwriting
            // AdminForcePasswordReset with any other reason except for None. This is because
            // an AdminForcePasswordReset will always force a user to update their password to a password that meets the policy.
            yield this.masterPasswordService.setForceSetPasswordReason(ForceSetPasswordReason.WeakMasterPassword, authResult.userId);
        });
    }
    getMasterPasswordPolicyOptionsFromResponse(response) {
        if (response == null) {
            return null;
        }
        return MasterPasswordPolicyOptions.fromResponse(response.masterPasswordPolicy);
    }
    evaluateMasterPassword({ masterPassword, email }, options) {
        var _a;
        const passwordStrength = (_a = this.passwordStrengthService.getPasswordStrength(masterPassword, email)) === null || _a === void 0 ? void 0 : _a.score;
        return this.policyService.evaluateMasterPassword(passwordStrength, masterPassword, options);
    }
    exportCache() {
        return {
            password: this.cache.value,
        };
    }
    logInNewDeviceVerification(deviceVerificationOtp) {
        return password_login_strategy_awaiter(this, void 0, void 0, function* () {
            var _a;
            const data = this.cache.value;
            data.tokenRequest.newDeviceOtp = deviceVerificationOtp;
            this.cache.next(data);
            const [authResult] = yield this.startLogIn();
            authResult.masterPassword = (_a = this.cache.value["masterPassword"]) !== null && _a !== void 0 ? _a : null;
            return authResult;
        });
    }
    /**
     * Override to handle the WeakMasterPassword reason if no other reason is set.
     * @param authResult - The authentication result
     * @param userId - The user ID
     */
    processForceSetPasswordReason(adminForcePasswordReset, userId) {
        const _super = Object.create(null, {
            processForceSetPasswordReason: { get: () => super.processForceSetPasswordReason }
        });
        return password_login_strategy_awaiter(this, void 0, void 0, function* () {
            // handle any existing reasons
            const adminForcePasswordResetFlagSet = yield _super.processForceSetPasswordReason.call(this, adminForcePasswordReset, userId);
            // If we are already processing an admin force password reset, don't process other reasons
            if (adminForcePasswordResetFlagSet) {
                return false;
            }
            // If we have a cached weak password reason from login/logInTwoFactor apply it
            const cachedReason = this.cache.value.forcePasswordResetReason;
            if (cachedReason !== ForceSetPasswordReason.None) {
                yield this.masterPasswordService.setForceSetPasswordReason(cachedReason, userId);
                return true;
            }
            // If none of the conditions are met, return false
            return false;
        });
    }
}

;// ../../libs/common/src/auth/models/request/identity-token/sso-token.request.ts



class SsoTokenRequest extends TokenRequest {
    constructor(code, codeVerifier, redirectUri, twoFactor, device) {
        super(twoFactor, device);
        this.code = code;
        this.codeVerifier = codeVerifier;
        this.redirectUri = redirectUri;
        this.twoFactor = twoFactor;
    }
    toIdentityToken(clientId) {
        const obj = super.toIdentityToken(clientId);
        obj.grant_type = "authorization_code";
        obj.code = this.code;
        obj.code_verifier = this.codeVerifier;
        obj.redirect_uri = this.redirectUri;
        return obj;
    }
    static fromJSON(json) {
        return Object.assign(Object.create(SsoTokenRequest.prototype), json, {
            device: json.device ? DeviceRequest.fromJSON(json.device) : undefined,
            twoFactor: json.twoFactor
                ? Object.assign(new TokenTwoFactorRequest(), json.twoFactor)
                : undefined,
        });
    }
}

;// ../../libs/common/src/enums/client-type.enum.ts


;// ../../libs/common/src/enums/device-type.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var DeviceType;
(function (DeviceType) {
    DeviceType[DeviceType["Android"] = 0] = "Android";
    DeviceType[DeviceType["iOS"] = 1] = "iOS";
    DeviceType[DeviceType["ChromeExtension"] = 2] = "ChromeExtension";
    DeviceType[DeviceType["FirefoxExtension"] = 3] = "FirefoxExtension";
    DeviceType[DeviceType["OperaExtension"] = 4] = "OperaExtension";
    DeviceType[DeviceType["EdgeExtension"] = 5] = "EdgeExtension";
    DeviceType[DeviceType["WindowsDesktop"] = 6] = "WindowsDesktop";
    DeviceType[DeviceType["MacOsDesktop"] = 7] = "MacOsDesktop";
    DeviceType[DeviceType["LinuxDesktop"] = 8] = "LinuxDesktop";
    DeviceType[DeviceType["ChromeBrowser"] = 9] = "ChromeBrowser";
    DeviceType[DeviceType["FirefoxBrowser"] = 10] = "FirefoxBrowser";
    DeviceType[DeviceType["OperaBrowser"] = 11] = "OperaBrowser";
    DeviceType[DeviceType["EdgeBrowser"] = 12] = "EdgeBrowser";
    DeviceType[DeviceType["IEBrowser"] = 13] = "IEBrowser";
    DeviceType[DeviceType["UnknownBrowser"] = 14] = "UnknownBrowser";
    DeviceType[DeviceType["AndroidAmazon"] = 15] = "AndroidAmazon";
    DeviceType[DeviceType["UWP"] = 16] = "UWP";
    DeviceType[DeviceType["SafariBrowser"] = 17] = "SafariBrowser";
    DeviceType[DeviceType["VivaldiBrowser"] = 18] = "VivaldiBrowser";
    DeviceType[DeviceType["VivaldiExtension"] = 19] = "VivaldiExtension";
    DeviceType[DeviceType["SafariExtension"] = 20] = "SafariExtension";
    DeviceType[DeviceType["SDK"] = 21] = "SDK";
    DeviceType[DeviceType["Server"] = 22] = "Server";
    DeviceType[DeviceType["WindowsCLI"] = 23] = "WindowsCLI";
    DeviceType[DeviceType["MacOsCLI"] = 24] = "MacOsCLI";
    DeviceType[DeviceType["LinuxCLI"] = 25] = "LinuxCLI";
    DeviceType[DeviceType["DuckDuckGoBrowser"] = 26] = "DuckDuckGoBrowser";
})(DeviceType || (DeviceType = {}));
const DeviceTypeMetadata = {
    [DeviceType.Android]: { category: "mobile", platform: "Android" },
    [DeviceType.iOS]: { category: "mobile", platform: "iOS" },
    [DeviceType.AndroidAmazon]: { category: "mobile", platform: "Amazon" },
    [DeviceType.ChromeExtension]: { category: "extension", platform: "Chrome" },
    [DeviceType.FirefoxExtension]: { category: "extension", platform: "Firefox" },
    [DeviceType.OperaExtension]: { category: "extension", platform: "Opera" },
    [DeviceType.EdgeExtension]: { category: "extension", platform: "Edge" },
    [DeviceType.VivaldiExtension]: { category: "extension", platform: "Vivaldi" },
    [DeviceType.SafariExtension]: { category: "extension", platform: "Safari" },
    [DeviceType.ChromeBrowser]: { category: "webApp", platform: "Chrome" },
    [DeviceType.FirefoxBrowser]: { category: "webApp", platform: "Firefox" },
    [DeviceType.OperaBrowser]: { category: "webApp", platform: "Opera" },
    [DeviceType.EdgeBrowser]: { category: "webApp", platform: "Edge" },
    [DeviceType.IEBrowser]: { category: "webApp", platform: "IE" },
    [DeviceType.SafariBrowser]: { category: "webApp", platform: "Safari" },
    [DeviceType.VivaldiBrowser]: { category: "webApp", platform: "Vivaldi" },
    [DeviceType.DuckDuckGoBrowser]: { category: "webApp", platform: "DuckDuckGo" },
    [DeviceType.UnknownBrowser]: { category: "webApp", platform: "Unknown" },
    [DeviceType.WindowsDesktop]: { category: "desktop", platform: "Windows" },
    [DeviceType.MacOsDesktop]: { category: "desktop", platform: "macOS" },
    [DeviceType.LinuxDesktop]: { category: "desktop", platform: "Linux" },
    [DeviceType.UWP]: { category: "desktop", platform: "Windows UWP" },
    [DeviceType.WindowsCLI]: { category: "cli", platform: "Windows" },
    [DeviceType.MacOsCLI]: { category: "cli", platform: "macOS" },
    [DeviceType.LinuxCLI]: { category: "cli", platform: "Linux" },
    [DeviceType.SDK]: { category: "sdk", platform: "" },
    [DeviceType.Server]: { category: "server", platform: "" },
};

;// ../../libs/common/src/enums/http-status-code.enum.ts
/**
 * Hypertext Transfer Protocol (HTTP) response status codes.
 *
 * @see {@link https://en.wikipedia.org/wiki/List_of_HTTP_status_codes}
 * src: https://gist.github.com/RWOverdijk/6cef816cfdf5722228e01cc05fd4b094
 */
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var HttpStatusCode;
(function (HttpStatusCode) {
    /**
     * The server has received the request headers and the client should proceed to send the request body
     * (in the case of a request for which a body needs to be sent; for example, a POST request).
     * Sending a large request body to a server after a request has been rejected for inappropriate headers would be inefficient.
     * To have a server check the request's headers, a client must send Expect: 100-continue as a header in its initial request
     * and receive a 100 Continue status code in response before sending the body. The response 417 Expectation Failed indicates the request should not be continued.
     */
    HttpStatusCode[HttpStatusCode["Continue"] = 100] = "Continue";
    /**
     * The requester has asked the server to switch protocols and the server has agreed to do so.
     */
    HttpStatusCode[HttpStatusCode["SwitchingProtocols"] = 101] = "SwitchingProtocols";
    /**
     * A WebDAV request may contain many sub-requests involving file operations, requiring a long time to complete the request.
     * This code indicates that the server has received and is processing the request, but no response is available yet.
     * This prevents the client from timing out and assuming the request was lost.
     */
    HttpStatusCode[HttpStatusCode["Processing"] = 102] = "Processing";
    // **********************************************************************************************************
    // 200s - SUCCESS
    // **********************************************************************************************************
    /**
     * Standard response for successful HTTP requests.
     * The actual response will depend on the request method used.
     * In a GET request, the response will contain an entity corresponding to the requested resource.
     * In a POST request, the response will contain an entity describing or containing the result of the action.
     */
    HttpStatusCode[HttpStatusCode["Ok"] = 200] = "Ok";
    /**
     * The request has been fulfilled, resulting in the creation of a new resource.
     */
    HttpStatusCode[HttpStatusCode["Created"] = 201] = "Created";
    /**
     * The request has been accepted for processing, but the processing has not been completed.
     * The request might or might not be eventually acted upon, and may be disallowed when processing occurs.
     */
    HttpStatusCode[HttpStatusCode["Accepted"] = 202] = "Accepted";
    /**
     * SINCE HTTP/1.1
     * The server is a transforming proxy that received a 200 OK from its origin,
     * but is returning a modified version of the origin's response.
     */
    HttpStatusCode[HttpStatusCode["NonAuthoritativeInformation"] = 203] = "NonAuthoritativeInformation";
    /**
     * The server successfully processed the request and is not returning any content.
     */
    HttpStatusCode[HttpStatusCode["NoContent"] = 204] = "NoContent";
    /**
     * The server successfully processed the request, but is not returning any content.
     * Unlike a 204 response, this response requires that the requester reset the document view.
     */
    HttpStatusCode[HttpStatusCode["ResetContent"] = 205] = "ResetContent";
    /**
     * The server is delivering only part of the resource (byte serving) due to a range header sent by the client.
     * The range header is used by HTTP clients to enable resuming of interrupted downloads,
     * or split a download into multiple simultaneous streams.
     */
    HttpStatusCode[HttpStatusCode["PartialContent"] = 206] = "PartialContent";
    /**
     * The message body that follows is an XML message and can contain a number of separate response codes,
     * depending on how many sub-requests were made.
     */
    HttpStatusCode[HttpStatusCode["MultiStatus"] = 207] = "MultiStatus";
    /**
     * The members of a DAV binding have already been enumerated in a preceding part of the (multistatus) response,
     * and are not being included again.
     */
    HttpStatusCode[HttpStatusCode["AlreadyReported"] = 208] = "AlreadyReported";
    /**
     * The server has fulfilled a request for the resource,
     * and the response is a representation of the result of one or more instance-manipulations applied to the current instance.
     */
    HttpStatusCode[HttpStatusCode["ImUsed"] = 226] = "ImUsed";
    // **********************************************************************************************************
    // 300s - Redirections
    // **********************************************************************************************************
    /**
     * Indicates multiple options for the resource from which the client may choose (via agent-driven content negotiation).
     * For example, this code could be used to present multiple video format options,
     * to list files with different filename extensions, or to suggest word-sense disambiguation.
     */
    HttpStatusCode[HttpStatusCode["MultipleChoices"] = 300] = "MultipleChoices";
    /**
     * This and all future requests should be directed to the given URI.
     */
    HttpStatusCode[HttpStatusCode["MovedPermanently"] = 301] = "MovedPermanently";
    /**
     * This is an example of industry practice contradicting the standard.
     * The HTTP/1.0 specification (RFC 1945) required the client to perform a temporary redirect
     * (the original describing phrase was "Moved Temporarily"), but popular browsers implemented 302
     * with the functionality of a 303 See Other. Therefore, HTTP/1.1 added status codes 303 and 307
     * to distinguish between the two behaviours. However, some Web applications and frameworks
     * use the 302 status code as if it were the 303.
     */
    HttpStatusCode[HttpStatusCode["Found"] = 302] = "Found";
    /**
     * SINCE HTTP/1.1
     * The response to the request can be found under another URI using a GET method.
     * When received in response to a POST (or PUT/DELETE), the client should presume that
     * the server has received the data and should issue a redirect with a separate GET message.
     */
    HttpStatusCode[HttpStatusCode["SeeOther"] = 303] = "SeeOther";
    /**
     * Indicates that the resource has not been modified since the version specified by the request headers If-Modified-Since or If-None-Match.
     * In such case, there is no need to retransmit the resource since the client still has a previously-downloaded copy.
     */
    HttpStatusCode[HttpStatusCode["NotModified"] = 304] = "NotModified";
    /**
     * SINCE HTTP/1.1
     * The requested resource is available only through a proxy, the address for which is provided in the response.
     * Many HTTP clients (such as Mozilla and Internet Explorer) do not correctly handle responses with this status code, primarily for security reasons.
     */
    HttpStatusCode[HttpStatusCode["UseProxy"] = 305] = "UseProxy";
    /**
     * No longer used. Originally meant "Subsequent requests should use the specified proxy."
     */
    HttpStatusCode[HttpStatusCode["SwitchProxy"] = 306] = "SwitchProxy";
    /**
     * SINCE HTTP/1.1
     * In this case, the request should be repeated with another URI; however, future requests should still use the original URI.
     * In contrast to how 302 was historically implemented, the request method is not allowed to be changed when reissuing the original request.
     * For example, a POST request should be repeated using another POST request.
     */
    HttpStatusCode[HttpStatusCode["TemporaryRedirect"] = 307] = "TemporaryRedirect";
    /**
     * The request and all future requests should be repeated using another URI.
     * 307 and 308 parallel the behaviors of 302 and 301, but do not allow the HTTP method to change.
     * So, for example, submitting a form to a permanently redirected resource may continue smoothly.
     */
    HttpStatusCode[HttpStatusCode["PermanentRedirect"] = 308] = "PermanentRedirect";
    // **********************************************************************************************************
    // 400s - Client / User messed up
    // **********************************************************************************************************
    /**
     * The server cannot or will not process the request due to an apparent client error
     * (e.g., malformed request syntax, too large size, invalid request message framing, or deceptive request routing).
     */
    HttpStatusCode[HttpStatusCode["BadRequest"] = 400] = "BadRequest";
    /**
     * Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet
     * been provided. The response must include a WWW-Authenticate header field containing a challenge applicable to the
     * requested resource. See Basic access authentication and Digest access authentication. 401 semantically means
     * "unauthenticated",i.e. the user does not have the necessary credentials.
     */
    HttpStatusCode[HttpStatusCode["Unauthorized"] = 401] = "Unauthorized";
    /**
     * Reserved for future use. The original intention was that this code might be used as part of some form of digital
     * cash or micro payment scheme, but that has not happened, and this code is not usually used.
     * Google Developers API uses this status if a particular developer has exceeded the daily limit on requests.
     */
    HttpStatusCode[HttpStatusCode["PaymentRequired"] = 402] = "PaymentRequired";
    /**
     * The request was valid, but the server is refusing action.
     * The user might not have the necessary permissions for a resource.
     */
    HttpStatusCode[HttpStatusCode["Forbidden"] = 403] = "Forbidden";
    /**
     * The requested resource could not be found but may be available in the future.
     * Subsequent requests by the client are permissible.
     */
    HttpStatusCode[HttpStatusCode["NotFound"] = 404] = "NotFound";
    /**
     * A request method is not supported for the requested resource;
     * for example, a GET request on a form that requires data to be presented via POST, or a PUT request on a read-only resource.
     */
    HttpStatusCode[HttpStatusCode["MethodNotAllowed"] = 405] = "MethodNotAllowed";
    /**
     * The requested resource is capable of generating only content not acceptable according to the Accept headers sent in the request.
     */
    HttpStatusCode[HttpStatusCode["NotAcceptable"] = 406] = "NotAcceptable";
    /**
     * The client must first authenticate itself with the proxy.
     */
    HttpStatusCode[HttpStatusCode["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired";
    /**
     * The server timed out waiting for the request.
     * According to HTTP specifications:
     * "The client did not produce a request within the time that the server was prepared to wait. The client MAY repeat the request without modifications at any later time."
     */
    HttpStatusCode[HttpStatusCode["RequestTimeout"] = 408] = "RequestTimeout";
    /**
     * Indicates that the request could not be processed because of conflict in the request,
     * such as an edit conflict between multiple simultaneous updates.
     */
    HttpStatusCode[HttpStatusCode["Conflict"] = 409] = "Conflict";
    /**
     * Indicates that the resource requested is no longer available and will not be available again.
     * This should be used when a resource has been intentionally removed and the resource should be purged.
     * Upon receiving a 410 status code, the client should not request the resource in the future.
     * Clients such as search engines should remove the resource from their indices.
     * Most use cases do not require clients and search engines to purge the resource, and a "404 Not Found" may be used instead.
     */
    HttpStatusCode[HttpStatusCode["Gone"] = 410] = "Gone";
    /**
     * The request did not specify the length of its content, which is required by the requested resource.
     */
    HttpStatusCode[HttpStatusCode["LengthRequired"] = 411] = "LengthRequired";
    /**
     * The server does not meet one of the preconditions that the requester put on the request.
     */
    HttpStatusCode[HttpStatusCode["PreconditionFailed"] = 412] = "PreconditionFailed";
    /**
     * The request is larger than the server is willing or able to process. Previously called "Request Entity Too Large".
     */
    HttpStatusCode[HttpStatusCode["PayloadTooLarge"] = 413] = "PayloadTooLarge";
    /**
     * The URI provided was too long for the server to process. Often the result of too much data being encoded as a query-string of a GET request,
     * in which case it should be converted to a POST request.
     * Called "Request-URI Too Long" previously.
     */
    HttpStatusCode[HttpStatusCode["UriTooLong"] = 414] = "UriTooLong";
    /**
     * The request entity has a media type which the server or resource does not support.
     * For example, the client uploads an image as image/svg+xml, but the server requires that images use a different format.
     */
    HttpStatusCode[HttpStatusCode["UnsupportedMediaType"] = 415] = "UnsupportedMediaType";
    /**
     * The client has asked for a portion of the file (byte serving), but the server cannot supply that portion.
     * For example, if the client asked for a part of the file that lies beyond the end of the file.
     * Called "Requested Range Not Satisfiable" previously.
     */
    HttpStatusCode[HttpStatusCode["RangeNotSatisfiable"] = 416] = "RangeNotSatisfiable";
    /**
     * The server cannot meet the requirements of the Expect request-header field.
     */
    HttpStatusCode[HttpStatusCode["ExpectationFailed"] = 417] = "ExpectationFailed";
    /**
     * This code was defined in 1998 as one of the traditional IETF April Fools' jokes, in RFC 2324, Hyper Text Coffee Pot Control Protocol,
     * and is not expected to be implemented by actual HTTP servers. The RFC specifies this code should be returned by
     * teapots requested to brew coffee. This HTTP status is used as an Easter egg in some websites, including Google.com.
     */
    HttpStatusCode[HttpStatusCode["IAmATeapot"] = 418] = "IAmATeapot";
    /**
     * The request was directed at a server that is not able to produce a response (for example because a connection reuse).
     */
    HttpStatusCode[HttpStatusCode["MisdirectedRequest"] = 421] = "MisdirectedRequest";
    /**
     * The request was well-formed but was unable to be followed due to semantic errors.
     */
    HttpStatusCode[HttpStatusCode["UnprocessableEntity"] = 422] = "UnprocessableEntity";
    /**
     * The resource that is being accessed is locked.
     */
    HttpStatusCode[HttpStatusCode["Locked"] = 423] = "Locked";
    /**
     * The request failed due to failure of a previous request (e.g., a PROPPATCH).
     */
    HttpStatusCode[HttpStatusCode["FailedDependency"] = 424] = "FailedDependency";
    /**
     * The client should switch to a different protocol such as TLS/1.0, given in the Upgrade header field.
     */
    HttpStatusCode[HttpStatusCode["UpgradeRequired"] = 426] = "UpgradeRequired";
    /**
     * The origin server requires the request to be conditional.
     * Intended to prevent "the 'lost update' problem, where a client
     * GETs a resource's state, modifies it, and PUTs it back to the server,
     * when meanwhile a third party has modified the state on the server, leading to a conflict."
     */
    HttpStatusCode[HttpStatusCode["PreconditionRequired"] = 428] = "PreconditionRequired";
    /**
     * The user has sent too many requests in a given amount of time. Intended for use with rate-limiting schemes.
     */
    HttpStatusCode[HttpStatusCode["TooManyRequests"] = 429] = "TooManyRequests";
    /**
     * The server is unwilling to process the request because either an individual header field,
     * or all the header fields collectively, are too large.
     */
    HttpStatusCode[HttpStatusCode["RequestHeaderFieldsTooLarge"] = 431] = "RequestHeaderFieldsTooLarge";
    /**
     * A server operator has received a legal demand to deny access to a resource or to a set of resources
     * that includes the requested resource. The code 451 was chosen as a reference to the novel Fahrenheit 451.
     */
    HttpStatusCode[HttpStatusCode["UnavailableForLegalReasons"] = 451] = "UnavailableForLegalReasons";
    // **********************************************************************************************************
    // 500s - Server messed up
    // **********************************************************************************************************
    /**
     * A generic error message, given when an unexpected condition was encountered and no more specific message is suitable.
     */
    HttpStatusCode[HttpStatusCode["InternalServerError"] = 500] = "InternalServerError";
    /**
     * The server either does not recognize the request method, or it lacks the ability to fulfill the request.
     * Usually this implies future availability (e.g., a new feature of a web-service API).
     */
    HttpStatusCode[HttpStatusCode["NotImplemented"] = 501] = "NotImplemented";
    /**
     * The server was acting as a gateway or proxy and received an invalid response from the upstream server.
     */
    HttpStatusCode[HttpStatusCode["BadGateway"] = 502] = "BadGateway";
    /**
     * The server is currently unavailable (because it is overloaded or down for maintenance).
     * Generally, this is a temporary state.
     */
    HttpStatusCode[HttpStatusCode["ServiceUnavailable"] = 503] = "ServiceUnavailable";
    /**
     * The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.
     */
    HttpStatusCode[HttpStatusCode["GatewayTimeout"] = 504] = "GatewayTimeout";
    /**
     * The server does not support the HTTP protocol version used in the request
     */
    HttpStatusCode[HttpStatusCode["HttpVersionNotSupported"] = 505] = "HttpVersionNotSupported";
    /**
     * Transparent content negotiation for the request results in a circular reference.
     */
    HttpStatusCode[HttpStatusCode["VariantAlsoNegotiates"] = 506] = "VariantAlsoNegotiates";
    /**
     * The server is unable to store the representation needed to complete the request.
     */
    HttpStatusCode[HttpStatusCode["InsufficientStorage"] = 507] = "InsufficientStorage";
    /**
     * The server detected an infinite loop while processing the request.
     */
    HttpStatusCode[HttpStatusCode["LoopDetected"] = 508] = "LoopDetected";
    /**
     * Further extensions to the request are required for the server to fulfill it.
     */
    HttpStatusCode[HttpStatusCode["NotExtended"] = 510] = "NotExtended";
    /**
     * The client needs to authenticate to gain network access.
     * Intended for use by intercepting proxies used to control access to the network (e.g., "captive portals" used
     * to require agreement to Terms of Service before granting full Internet access via a Wi-Fi hotspot).
     */
    HttpStatusCode[HttpStatusCode["NetworkAuthenticationRequired"] = 511] = "NetworkAuthenticationRequired";
})(HttpStatusCode || (HttpStatusCode = {}));

;// ../../libs/common/src/enums/integration-type.enum.ts
const IntegrationType = Object.freeze({
    Integration: "integration",
    SDK: "sdk",
    SSO: "sso",
    SCIM: "scim",
    BWDC: "bwdc",
    EVENT: "event",
    DEVICE: "device",
});

;// ../../libs/common/src/enums/native-messaging-version.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var NativeMessagingVersion;
(function (NativeMessagingVersion) {
    NativeMessagingVersion[NativeMessagingVersion["One"] = 1] = "One";
    NativeMessagingVersion[NativeMessagingVersion["Latest"] = 1] = "Latest";
})(NativeMessagingVersion || (NativeMessagingVersion = {}));

;// ../../libs/common/src/enums/notification-type.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var NotificationType;
(function (NotificationType) {
    NotificationType[NotificationType["SyncCipherUpdate"] = 0] = "SyncCipherUpdate";
    NotificationType[NotificationType["SyncCipherCreate"] = 1] = "SyncCipherCreate";
    NotificationType[NotificationType["SyncLoginDelete"] = 2] = "SyncLoginDelete";
    NotificationType[NotificationType["SyncFolderDelete"] = 3] = "SyncFolderDelete";
    NotificationType[NotificationType["SyncCiphers"] = 4] = "SyncCiphers";
    NotificationType[NotificationType["SyncVault"] = 5] = "SyncVault";
    NotificationType[NotificationType["SyncOrgKeys"] = 6] = "SyncOrgKeys";
    NotificationType[NotificationType["SyncFolderCreate"] = 7] = "SyncFolderCreate";
    NotificationType[NotificationType["SyncFolderUpdate"] = 8] = "SyncFolderUpdate";
    NotificationType[NotificationType["SyncCipherDelete"] = 9] = "SyncCipherDelete";
    NotificationType[NotificationType["SyncSettings"] = 10] = "SyncSettings";
    NotificationType[NotificationType["LogOut"] = 11] = "LogOut";
    NotificationType[NotificationType["SyncSendCreate"] = 12] = "SyncSendCreate";
    NotificationType[NotificationType["SyncSendUpdate"] = 13] = "SyncSendUpdate";
    NotificationType[NotificationType["SyncSendDelete"] = 14] = "SyncSendDelete";
    NotificationType[NotificationType["AuthRequest"] = 15] = "AuthRequest";
    NotificationType[NotificationType["AuthRequestResponse"] = 16] = "AuthRequestResponse";
    NotificationType[NotificationType["SyncOrganizations"] = 17] = "SyncOrganizations";
    NotificationType[NotificationType["SyncOrganizationStatusChanged"] = 18] = "SyncOrganizationStatusChanged";
    NotificationType[NotificationType["SyncOrganizationCollectionSettingChanged"] = 19] = "SyncOrganizationCollectionSettingChanged";
    NotificationType[NotificationType["Notification"] = 20] = "Notification";
    NotificationType[NotificationType["NotificationStatus"] = 21] = "NotificationStatus";
    NotificationType[NotificationType["RefreshSecurityTasks"] = 22] = "RefreshSecurityTasks";
    NotificationType[NotificationType["OrganizationBankAccountVerified"] = 23] = "OrganizationBankAccountVerified";
    NotificationType[NotificationType["ProviderBankAccountVerified"] = 24] = "ProviderBankAccountVerified";
    NotificationType[NotificationType["SyncPolicy"] = 25] = "SyncPolicy";
    NotificationType[NotificationType["AutoConfirmMember"] = 26] = "AutoConfirmMember";
})(NotificationType || (NotificationType = {}));

;// ../../libs/common/src/enums/push-notification-logout-reason.enum.ts
const PushNotificationLogOutReasonType = Object.freeze({
    KdfChange: 0,
});

;// ../../libs/common/src/enums/index.ts








;// ../../libs/auth/src/common/login-strategies/sso-login.strategy.ts
var sso_login_strategy_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore







class SsoLoginStrategyData {
    constructor() {
        /** Whether unlock service should be used for Key Connector in this login flow. */
        this.unlockServiceForKeyConnectorLogin = false;
    }
    static fromJSON(obj) {
        return Object.assign(new SsoLoginStrategyData(), obj, {
            tokenRequest: SsoTokenRequest.fromJSON(obj.tokenRequest),
        });
    }
}
class SsoLoginStrategy extends LoginStrategy {
    constructor(data, keyConnectorService, unlockService, deviceTrustService, authRequestService, ...sharedDeps) {
        super(...sharedDeps);
        this.keyConnectorService = keyConnectorService;
        this.unlockService = unlockService;
        this.deviceTrustService = deviceTrustService;
        this.authRequestService = authRequestService;
        this.cache = new external_rxjs_namespaceObject.BehaviorSubject(data);
        this.email$ = this.cache.pipe((0,external_rxjs_namespaceObject.map)((state) => state.email));
        this.orgId$ = this.cache.pipe((0,external_rxjs_namespaceObject.map)((state) => state.orgId));
        this.ssoEmail2FaSessionToken$ = this.cache.pipe((0,external_rxjs_namespaceObject.map)((state) => state.ssoEmail2FaSessionToken));
    }
    logIn(credentials) {
        return sso_login_strategy_awaiter(this, void 0, void 0, function* () {
            const data = new SsoLoginStrategyData();
            data.unlockServiceForKeyConnectorLogin = yield this.configService.getFeatureFlag(feature_flag_enum_FeatureFlag.UnlockKeyConnectorWithSdk);
            data.orgId = credentials.orgId;
            data.userEnteredEmail = credentials.email;
            const deviceRequest = yield this.buildDeviceRequest();
            this.logService.info("Logging in with appId %s.", deviceRequest.identifier);
            data.tokenRequest = new SsoTokenRequest(credentials.code, credentials.codeVerifier, credentials.redirectUrl, yield this.buildTwoFactor(credentials.twoFactor, credentials.email), deviceRequest);
            this.cache.next(data);
            const [ssoAuthResult] = yield this.startLogIn();
            const email = ssoAuthResult.email;
            const ssoEmail2FaSessionToken = ssoAuthResult.ssoEmail2FaSessionToken;
            this.cache.next(Object.assign(Object.assign({}, this.cache.value), { email,
                ssoEmail2FaSessionToken }));
            return ssoAuthResult;
        });
    }
    setMasterKey(tokenResponse, userId) {
        return sso_login_strategy_awaiter(this, void 0, void 0, function* () {
            // The only way we can be setting a master key at this point is if we are using Key Connector.
            // First, check to make sure that we should do so based on the token response.
            if (this.shouldSetMasterKeyFromKeyConnector(tokenResponse)) {
                // If we're here, we know that the user should use Key Connector (they have a KeyConnectorUrl) and does not have a master password.
                // We can now check the key on the token response to see whether they are a brand new user or an existing user.
                // The presence of a masterKeyEncryptedUserKey indicates that the user has already been provisioned in Key Connector.
                const newSsoUser = tokenResponse.key == null;
                if (newSsoUser) {
                    // Store Key Connector domain confirmation data in state instead of AuthResult
                    yield this.keyConnectorService.setNewSsoUserKeyConnectorConversionData({
                        kdfConfig: tokenResponse.kdfConfig,
                        keyConnectorUrl: this.getKeyConnectorUrl(tokenResponse),
                        organizationId: this.cache.value.orgId,
                    }, userId);
                }
                else {
                    const keyConnectorUrl = this.getKeyConnectorUrl(tokenResponse);
                    if (!this.cache.value.unlockServiceForKeyConnectorLogin) {
                        yield this.keyConnectorService.setMasterKeyFromUrl(keyConnectorUrl, userId);
                    }
                }
            }
        });
    }
    /**
     * Determines if it is possible set the `masterKey` from Key Connector.
     * @param tokenResponse
     * @returns `true` if the master key can be set from Key Connector, `false` otherwise
     */
    shouldSetMasterKeyFromKeyConnector(tokenResponse) {
        var _a;
        const userDecryptionOptions = tokenResponse === null || tokenResponse === void 0 ? void 0 : tokenResponse.userDecryptionOptions;
        if (userDecryptionOptions != null) {
            const userHasMasterPassword = userDecryptionOptions.hasMasterPassword;
            const userHasKeyConnectorUrl = ((_a = userDecryptionOptions.keyConnectorOption) === null || _a === void 0 ? void 0 : _a.keyConnectorUrl) != null;
            // In order for us to set the master key from Key Connector, we need to have a Key Connector URL
            // and the user must not have a master password.
            return userHasKeyConnectorUrl && !userHasMasterPassword;
        }
    }
    getKeyConnectorUrl(tokenResponse) {
        var _a;
        const userDecryptionOptions = tokenResponse === null || tokenResponse === void 0 ? void 0 : tokenResponse.userDecryptionOptions;
        return (_a = userDecryptionOptions === null || userDecryptionOptions === void 0 ? void 0 : userDecryptionOptions.keyConnectorOption) === null || _a === void 0 ? void 0 : _a.keyConnectorUrl;
    }
    // TODO: future passkey login strategy will need to support setting user key (decrypting via TDE or admin approval request)
    // so might be worth moving this logic to a common place (base login strategy or a separate service?)
    setUserKey(tokenResponse, userId) {
        return sso_login_strategy_awaiter(this, void 0, void 0, function* () {
            const masterKeyEncryptedUserKey = tokenResponse.key;
            // Note: masterKeyEncryptedUserKey is undefined for SSO JIT provisioned users
            // on account creation and subsequent logins (confirmed or unconfirmed)
            // but that is fine for TDE so we cannot return if it is undefined
            if (masterKeyEncryptedUserKey) {
                // set the master key encrypted user key if it exists
                yield this.masterPasswordService.setMasterKeyEncryptedUserKey(masterKeyEncryptedUserKey, userId);
            }
            const userDecryptionOptions = tokenResponse === null || tokenResponse === void 0 ? void 0 : tokenResponse.userDecryptionOptions;
            if (tokenResponse.canUnlockWithKeyConnector() &&
                this.cache.value.unlockServiceForKeyConnectorLogin) {
                yield this.unlockService.unlockWithKeyConnector(userId, tokenResponse.intoKeyConnectorUnlockData());
                return;
            }
            // Note: TDE and key connector are mutually exclusive
            if (userDecryptionOptions === null || userDecryptionOptions === void 0 ? void 0 : userDecryptionOptions.trustedDeviceOption) {
                this.logService.info("Attempting to set user key with approved admin auth request.");
                // Try to use the user key from an approved admin request if it exists.
                // Using it will clear it from state and future requests will use the device key.
                yield this.trySetUserKeyWithApprovedAdminRequestIfExists(userId);
                const hasUserKey = yield this.keyService.hasUserKey(userId);
                // Only try to set user key with device key if admin approval request was not successful.
                if (!hasUserKey) {
                    this.logService.info("Attempting to set user key with device key.");
                    yield this.trySetUserKeyWithDeviceKey(tokenResponse, userId);
                }
            }
            else if (masterKeyEncryptedUserKey != null &&
                this.getKeyConnectorUrl(tokenResponse) != null &&
                !this.cache.value.unlockServiceForKeyConnectorLogin) {
                // Key connector enabled for user
                yield this.trySetUserKeyWithMasterKey(userId);
            }
            // Note: In the traditional SSO flow with MP without key connector, the lock component
            // is responsible for deriving master key from MP entry and then decrypting the user key
        });
    }
    trySetUserKeyWithApprovedAdminRequestIfExists(userId) {
        return sso_login_strategy_awaiter(this, void 0, void 0, function* () {
            // At this point a user could have an admin auth request that has been approved
            const adminAuthReqStorable = yield this.authRequestService.getAdminAuthRequest(userId);
            if (!adminAuthReqStorable) {
                return;
            }
            // Call server to see if admin auth request has been approved
            let adminAuthReqResponse;
            try {
                adminAuthReqResponse = yield this.apiService.getAuthRequest(adminAuthReqStorable.id);
            }
            catch (error) {
                if (error instanceof ErrorResponse && error.statusCode === HttpStatusCode.NotFound) {
                    // if we get a 404, it means the auth request has been deleted so clear it from storage
                    yield this.authRequestService.clearAdminAuthRequest(userId);
                }
                // Always return on an error here as we don't want to block the user from logging in
                return;
            }
            if (adminAuthReqResponse === null || adminAuthReqResponse === void 0 ? void 0 : adminAuthReqResponse.requestApproved) {
                yield this.authRequestService.setUserKeyAfterDecryptingSharedUserKey(adminAuthReqResponse, adminAuthReqStorable.privateKey, userId);
                if (yield this.keyService.hasUserKey(userId)) {
                    // Now that we have a decrypted user key in memory, we can check if we
                    // need to establish trust on the current device
                    yield this.deviceTrustService.trustDeviceIfRequired(userId);
                    // if we successfully decrypted the user key, we can delete the admin auth request out of state
                    // TODO: eventually we post and clean up DB as well once consumed on client
                    yield this.authRequestService.clearAdminAuthRequest(userId);
                    // This notification will be picked up by the SsoComponent to handle displaying a toast to the user
                    this.authRequestService.emitAdminLoginApproved();
                }
            }
        });
    }
    trySetUserKeyWithDeviceKey(tokenResponse, userId) {
        return sso_login_strategy_awaiter(this, void 0, void 0, function* () {
            var _a;
            const trustedDeviceOption = (_a = tokenResponse.userDecryptionOptions) === null || _a === void 0 ? void 0 : _a.trustedDeviceOption;
            if (!trustedDeviceOption) {
                this.logService.error("Unable to set user key due to missing trustedDeviceOption.");
                return;
            }
            const deviceKey = yield this.deviceTrustService.getDeviceKey(userId);
            const encDevicePrivateKey = trustedDeviceOption === null || trustedDeviceOption === void 0 ? void 0 : trustedDeviceOption.encryptedPrivateKey;
            const encUserKey = trustedDeviceOption === null || trustedDeviceOption === void 0 ? void 0 : trustedDeviceOption.encryptedUserKey;
            if (!deviceKey || !encDevicePrivateKey || !encUserKey) {
                if (!deviceKey) {
                    this.logService.warning("Unable to set user key due to missing device key.");
                }
                else if (!encDevicePrivateKey || !encUserKey) {
                    // Tell the server that we have a device key, but received no decryption keys
                    yield this.deviceTrustService.recordDeviceTrustLoss();
                }
                if (!encDevicePrivateKey) {
                    this.logService.warning("Unable to set user key due to missing encrypted device private key.");
                }
                if (!encUserKey) {
                    this.logService.warning("Unable to set user key due to missing encrypted user key.");
                }
                return;
            }
            const userKey = yield this.deviceTrustService.decryptUserKeyWithDeviceKey(userId, encDevicePrivateKey, encUserKey, deviceKey);
            if (userKey) {
                yield this.keyService.setUserKey(userKey, userId);
            }
        });
    }
    trySetUserKeyWithMasterKey(userId) {
        return sso_login_strategy_awaiter(this, void 0, void 0, function* () {
            const masterKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.masterPasswordService.masterKey$(userId));
            // There are two scenarios in which the master key is not set here:
            // 1. If the user has a master password and is using Key Connector. In that case, we cannot set the master key
            // because the user hasn't entered their master password yet.
            // 2. For new users with Key Connector, we will not have a master key yet, since Key Connector domain
            // has to be confirmed first.
            // In both cases, we'll return here and let the migration to Key Connector handle setting the master key.
            if (!masterKey) {
                return;
            }
            const userKey = yield this.masterPasswordService.decryptUserKeyWithMasterKey(masterKey, userId);
            yield this.keyService.setUserKey(userKey, userId);
        });
    }
    setAccountCryptographicState(tokenResponse, userId) {
        return sso_login_strategy_awaiter(this, void 0, void 0, function* () {
            if (tokenResponse.accountKeysResponseModel) {
                yield this.accountCryptographicStateService.setAccountCryptographicState(tokenResponse.accountKeysResponseModel.toWrappedAccountCryptographicState(), userId);
            }
        });
    }
    exportCache() {
        return {
            sso: this.cache.value,
        };
    }
    /**
     * Override to handle SSO-specific ForceSetPasswordReason flags,including TdeOffboarding,
     * TdeUserWithoutPasswordHasPasswordResetPermission, and SsoNewJitProvisionedUser cases.
     * @param authResult - The authentication result
     * @param userId - The user ID
     */
    processForceSetPasswordReason(adminForcePasswordReset, userId) {
        const _super = Object.create(null, {
            processForceSetPasswordReason: { get: () => super.processForceSetPasswordReason }
        });
        return sso_login_strategy_awaiter(this, void 0, void 0, function* () {
            var _a, _b, _c, _d;
            // handle any existing reasons
            const adminForcePasswordResetFlagSet = yield _super.processForceSetPasswordReason.call(this, adminForcePasswordReset, userId);
            // If we are already processing an admin force password reset, don't process other reasons
            if (adminForcePasswordResetFlagSet) {
                return false;
            }
            // Check for TDE-related conditions
            const userDecryptionOptions = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.userDecryptionOptionsService.userDecryptionOptionsById$(userId));
            if (!userDecryptionOptions) {
                return false;
            }
            // Check for TDE offboarding - user is being offboarded from TDE and needs to set a password on a trusted device
            if ((_a = userDecryptionOptions.trustedDeviceOption) === null || _a === void 0 ? void 0 : _a.isTdeOffboarding) {
                yield this.masterPasswordService.setForceSetPasswordReason(ForceSetPasswordReason.TdeOffboarding, userId);
                return true;
            }
            // If a TDE org user in an offboarding state logs in on an untrusted device, then they will receive their existing userKeyEncryptedPrivateKey from the server, but
            // TDE would not have been able to decrypt their user key b/c we don't send down TDE as a valid decryption option, so the user key will be unavilable here for TDE org users on untrusted devices.
            // - UserDecryptionOptions.trustedDeviceOption is undefined -- device isn't trusted.
            // - UserDecryptionOptions.hasMasterPassword is false -- user doesn't have a master password.
            // - UserDecryptionOptions.UsesKeyConnector is undefined. -- they aren't using key connector
            // - UserKey is not set after successful login -- because automatic decryption is not available
            // - userKeyEncryptedPrivateKey is set after successful login -- this is the key differentiator between a TDE org user logging into an untrusted device and MP encryption JIT provisioned user logging in for the first time.
            //     Why is that the case?  Because we set the userKeyEncryptedPrivateKey when we create the userKey, and this is serving as a proxy to tell us that the userKey has been created already (when enrolling in TDE).
            const hasUserKeyEncryptedPrivateKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.userEncryptedPrivateKey$(userId));
            const hasUserKey = yield this.keyService.hasUserKey(userId);
            // TODO: PM-23491 we should explore consolidating this logic into a flag on the server. It could be set when an org is switched from TDE to MP encryption for each org user.
            if (!userDecryptionOptions.trustedDeviceOption &&
                !userDecryptionOptions.hasMasterPassword &&
                !((_b = userDecryptionOptions.keyConnectorOption) === null || _b === void 0 ? void 0 : _b.keyConnectorUrl) &&
                hasUserKeyEncryptedPrivateKey &&
                !hasUserKey) {
                yield this.masterPasswordService.setForceSetPasswordReason(ForceSetPasswordReason.TdeOffboardingUntrustedDevice, userId);
                return true;
            }
            // Check if user has permission to set password but hasn't yet
            if (!userDecryptionOptions.hasMasterPassword &&
                ((_c = userDecryptionOptions.trustedDeviceOption) === null || _c === void 0 ? void 0 : _c.hasManageResetPasswordPermission)) {
                yield this.masterPasswordService.setForceSetPasswordReason(ForceSetPasswordReason.TdeUserWithoutPasswordHasPasswordResetPermission, userId);
                return true;
            }
            // Check for new SSO JIT provisioned user
            // If a user logs in via SSO but has no master password and no alternative encryption methods
            // Then they must be a newly provisioned user who needs to set up their encryption
            if (!userDecryptionOptions.hasMasterPassword &&
                !((_d = userDecryptionOptions.keyConnectorOption) === null || _d === void 0 ? void 0 : _d.keyConnectorUrl) &&
                !userDecryptionOptions.trustedDeviceOption) {
                yield this.masterPasswordService.setForceSetPasswordReason(ForceSetPasswordReason.SsoNewJitProvisionedUser, userId);
                return true;
            }
            // If none of the conditions are met, return false
            return false;
        });
    }
}

;// ../../libs/common/src/auth/models/request/identity-token/user-api-token.request.ts



class UserApiTokenRequest extends TokenRequest {
    constructor(clientId, clientSecret, twoFactor, device) {
        super(twoFactor, device);
        this.clientId = clientId;
        this.clientSecret = clientSecret;
        this.twoFactor = twoFactor;
    }
    toIdentityToken() {
        const obj = super.toIdentityToken(this.clientId);
        obj.scope = this.clientId.startsWith("organization") ? "api.organization" : "api";
        obj.grant_type = "client_credentials";
        obj.client_secret = this.clientSecret;
        return obj;
    }
    static fromJSON(json) {
        return Object.assign(Object.create(UserApiTokenRequest.prototype), json, {
            device: json.device ? DeviceRequest.fromJSON(json.device) : undefined,
            twoFactor: json.twoFactor
                ? Object.assign(new TokenTwoFactorRequest(), json.twoFactor)
                : undefined,
        });
    }
}

;// ../../libs/auth/src/common/login-strategies/user-api-login.strategy.ts
var user_api_login_strategy_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore




class UserApiLoginStrategyData {
    static fromJSON(obj) {
        return Object.assign(new UserApiLoginStrategyData(), obj, {
            tokenRequest: UserApiTokenRequest.fromJSON(obj.tokenRequest),
        });
    }
}
class UserApiLoginStrategy extends LoginStrategy {
    constructor(data, keyConnectorService, unlockService, ...sharedDeps) {
        super(...sharedDeps);
        this.keyConnectorService = keyConnectorService;
        this.unlockService = unlockService;
        this.cache = new external_rxjs_namespaceObject.BehaviorSubject(data);
    }
    logIn(credentials) {
        return user_api_login_strategy_awaiter(this, void 0, void 0, function* () {
            const data = new UserApiLoginStrategyData();
            data.tokenRequest = new UserApiTokenRequest(credentials.clientId, credentials.clientSecret, yield this.buildTwoFactor(), yield this.buildDeviceRequest());
            this.cache.next(data);
            const [authResult] = yield this.startLogIn();
            return authResult;
        });
    }
    setMasterKey(response, userId) {
        return user_api_login_strategy_awaiter(this, void 0, void 0, function* () {
            const sdkHandledKeyConnector = response.canUnlockWithKeyConnector() &&
                (yield this.configService.getFeatureFlag(feature_flag_enum_FeatureFlag.UnlockKeyConnectorWithSdk));
            if (!sdkHandledKeyConnector && response.apiUseKeyConnector) {
                const env = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.environmentService.environment$);
                const keyConnectorUrl = env.getKeyConnectorUrl();
                yield this.keyConnectorService.setMasterKeyFromUrl(keyConnectorUrl, userId);
            }
        });
    }
    setUserKey(response, userId) {
        return user_api_login_strategy_awaiter(this, void 0, void 0, function* () {
            const sdkHandledKeyConnector = response.canUnlockWithKeyConnector() &&
                (yield this.configService.getFeatureFlag(feature_flag_enum_FeatureFlag.UnlockKeyConnectorWithSdk));
            if (sdkHandledKeyConnector) {
                yield this.unlockService.unlockWithKeyConnector(userId, response.intoKeyConnectorUnlockData());
                return;
            }
            if (response.key) {
                yield this.masterPasswordService.setMasterKeyEncryptedUserKey(response.key, userId);
            }
            if (response.apiUseKeyConnector) {
                const masterKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.masterPasswordService.masterKey$(userId));
                if (masterKey) {
                    const userKey = yield this.masterPasswordService.decryptUserKeyWithMasterKey(masterKey, userId);
                    yield this.keyService.setUserKey(userKey, userId);
                }
            }
        });
    }
    setAccountCryptographicState(response, userId) {
        return user_api_login_strategy_awaiter(this, void 0, void 0, function* () {
            yield this.accountCryptographicStateService.setAccountCryptographicState(response.accountKeysResponseModel.toWrappedAccountCryptographicState(), userId);
        });
    }
    // Overridden to save client ID and secret to token service
    saveAccountInformation(tokenResponse) {
        const _super = Object.create(null, {
            saveAccountInformation: { get: () => super.saveAccountInformation }
        });
        return user_api_login_strategy_awaiter(this, void 0, void 0, function* () {
            const userId = yield _super.saveAccountInformation.call(this, tokenResponse);
            const vaultTimeoutAction = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.vaultTimeoutSettingsService.getVaultTimeoutActionByUserId$(userId));
            const vaultTimeout = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.vaultTimeoutSettingsService.getVaultTimeoutByUserId$(userId));
            const tokenRequest = this.cache.value.tokenRequest;
            yield this.tokenService.setClientId(tokenRequest.clientId, vaultTimeoutAction, vaultTimeout);
            yield this.tokenService.setClientSecret(tokenRequest.clientSecret, vaultTimeoutAction, vaultTimeout);
            return userId;
        });
    }
    exportCache() {
        return {
            userApiKey: this.cache.value,
        };
    }
}

;// ../../libs/common/src/auth/models/request/identity-token/webauthn-login-token.request.ts




class WebAuthnLoginTokenRequest extends TokenRequest {
    constructor(token, deviceResponse, device) {
        super(undefined, device);
        this.token = token;
        this.deviceResponse = deviceResponse;
    }
    toIdentityToken(clientId) {
        const obj = super.toIdentityToken(clientId);
        obj.grant_type = "webauthn";
        obj.token = this.token;
        // must be a string b/c sending as form encoded data
        obj.deviceResponse = JSON.stringify(this.deviceResponse);
        return obj;
    }
    static fromJSON(json) {
        return Object.assign(Object.create(WebAuthnLoginTokenRequest.prototype), json, {
            deviceResponse: WebAuthnLoginAssertionResponseRequest.fromJSON(json.deviceResponse),
            device: json.device ? DeviceRequest.fromJSON(json.device) : undefined,
            twoFactor: json.twoFactor
                ? Object.assign(new TokenTwoFactorRequest(), json.twoFactor)
                : undefined,
        });
    }
}

;// ../../libs/auth/src/common/login-strategies/webauthn-login.strategy.ts
var webauthn_login_strategy_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore





class WebAuthnLoginStrategyData {
    static fromJSON(obj) {
        return Object.assign(new WebAuthnLoginStrategyData(), obj, {
            tokenRequest: WebAuthnLoginTokenRequest.fromJSON(obj.tokenRequest),
            credentials: WebAuthnLoginCredentials.fromJSON(obj.credentials),
        });
    }
}
class WebAuthnLoginStrategy extends LoginStrategy {
    constructor(data, ...sharedDeps) {
        super(...sharedDeps);
        this.cache = new external_rxjs_namespaceObject.BehaviorSubject(data);
    }
    logIn(credentials) {
        return webauthn_login_strategy_awaiter(this, void 0, void 0, function* () {
            const data = new WebAuthnLoginStrategyData();
            data.credentials = credentials;
            data.tokenRequest = new WebAuthnLoginTokenRequest(credentials.token, credentials.deviceResponse, yield this.buildDeviceRequest());
            this.cache.next(data);
            const [authResult] = yield this.startLogIn();
            return authResult;
        });
    }
    logInTwoFactor() {
        return webauthn_login_strategy_awaiter(this, void 0, void 0, function* () {
            throw new Error("2FA not supported yet for WebAuthn Login.");
        });
    }
    setMasterKey(response, userId) {
        return webauthn_login_strategy_awaiter(this, void 0, void 0, function* () { });
    }
    setUserKey(idTokenResponse, userId) {
        return webauthn_login_strategy_awaiter(this, void 0, void 0, function* () {
            const masterKeyEncryptedUserKey = idTokenResponse.key;
            if (masterKeyEncryptedUserKey) {
                // set the master key encrypted user key if it exists
                yield this.masterPasswordService.setMasterKeyEncryptedUserKey(masterKeyEncryptedUserKey, userId);
            }
            const userDecryptionOptions = idTokenResponse === null || idTokenResponse === void 0 ? void 0 : idTokenResponse.userDecryptionOptions;
            if (userDecryptionOptions === null || userDecryptionOptions === void 0 ? void 0 : userDecryptionOptions.webAuthnPrfOption) {
                const credentials = this.cache.value.credentials;
                // confirm we still have the prf key
                if (!credentials.prfKey) {
                    return;
                }
                const webAuthnPrfOption = userDecryptionOptions.webAuthnPrfOption;
                // decrypt prf encrypted private key
                const privateKey = yield this.encryptService.unwrapDecapsulationKey(webAuthnPrfOption.encryptedPrivateKey, credentials.prfKey);
                // decrypt user key with private key
                const userKey = yield this.encryptService.decapsulateKeyUnsigned(new enc_string_EncString(webAuthnPrfOption.encryptedUserKey.encryptedString), privateKey);
                if (userKey) {
                    yield this.keyService.setUserKey(userKey, userId);
                }
            }
        });
    }
    setAccountCryptographicState(response, userId) {
        return webauthn_login_strategy_awaiter(this, void 0, void 0, function* () {
            yield this.accountCryptographicStateService.setAccountCryptographicState(response.accountKeysResponseModel.toWrappedAccountCryptographicState(), userId);
        });
    }
    exportCache() {
        return {
            webAuthn: this.cache.value,
        };
    }
}

;// ../../libs/auth/src/common/services/login-strategies/login-strategy.state.ts






/**
 * The current login strategy in use.
 */
const CURRENT_LOGIN_STRATEGY_KEY = new KeyDefinition(LOGIN_STRATEGY_MEMORY, "currentLoginStrategy", {
    deserializer: (data) => data,
});
/**
 * The expiration date for the login strategy cache.
 * Used as a backup to the timer set on the service.
 */
const CACHE_EXPIRATION_KEY = new KeyDefinition(LOGIN_STRATEGY_MEMORY, "loginStrategyCacheExpiration", {
    deserializer: (data) => (data ? new Date(data) : null),
});
/**
 * Auth Request notification for all instances of the login strategy service.
 * Note: this isn't an ideal approach, but allows both a background and
 * foreground instance to send out the notification.
 * TODO: Move to Auth Request service.
 */
const AUTH_REQUEST_PUSH_NOTIFICATION_KEY = new KeyDefinition(LOGIN_STRATEGY_MEMORY, "authRequestPushNotification", {
    deserializer: (data) => data,
});
/**
 * A cache for login strategies to use for data persistence through
 * the login process.
 */
const CACHE_KEY = new KeyDefinition(LOGIN_STRATEGY_MEMORY, "loginStrategyCache", {
    deserializer: (data) => {
        if (data == null) {
            return null;
        }
        return {
            password: data.password ? PasswordLoginStrategyData.fromJSON(data.password) : undefined,
            sso: data.sso ? SsoLoginStrategyData.fromJSON(data.sso) : undefined,
            userApiKey: data.userApiKey
                ? UserApiLoginStrategyData.fromJSON(data.userApiKey)
                : undefined,
            authRequest: data.authRequest
                ? AuthRequestLoginStrategyData.fromJSON(data.authRequest)
                : undefined,
            webAuthn: data.webAuthn ? WebAuthnLoginStrategyData.fromJSON(data.webAuthn) : undefined,
        };
    },
});

;// ../../libs/auth/src/common/services/login-strategies/login-strategy.service.ts
var login_strategy_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};









class LoginStrategyService {
    constructor(accountService, masterPasswordService, keyService, apiService, tokenService, appIdService, platformUtilsService, messagingService, logService, keyConnectorService, environmentService, stateService, twoFactorService, i18nService, encryptService, passwordStrengthService, policyService, deviceTrustService, authRequestService, userDecryptionOptionsService, stateProvider, billingAccountProfileStateService, vaultTimeoutSettingsService, kdfConfigService, configService, accountCryptographicStateService, passwordPreloginService, unlockService, loginStrategyCacheService, loginStrategySessionTimeoutService) {
        this.accountService = accountService;
        this.masterPasswordService = masterPasswordService;
        this.keyService = keyService;
        this.apiService = apiService;
        this.tokenService = tokenService;
        this.appIdService = appIdService;
        this.platformUtilsService = platformUtilsService;
        this.messagingService = messagingService;
        this.logService = logService;
        this.keyConnectorService = keyConnectorService;
        this.environmentService = environmentService;
        this.stateService = stateService;
        this.twoFactorService = twoFactorService;
        this.i18nService = i18nService;
        this.encryptService = encryptService;
        this.passwordStrengthService = passwordStrengthService;
        this.policyService = policyService;
        this.deviceTrustService = deviceTrustService;
        this.authRequestService = authRequestService;
        this.userDecryptionOptionsService = userDecryptionOptionsService;
        this.stateProvider = stateProvider;
        this.billingAccountProfileStateService = billingAccountProfileStateService;
        this.vaultTimeoutSettingsService = vaultTimeoutSettingsService;
        this.kdfConfigService = kdfConfigService;
        this.configService = configService;
        this.accountCryptographicStateService = accountCryptographicStateService;
        this.passwordPreloginService = passwordPreloginService;
        this.unlockService = unlockService;
        this.loginStrategyCacheService = loginStrategyCacheService;
        this.loginStrategySessionTimeoutService = loginStrategySessionTimeoutService;
        this.authRequestPushNotificationState = this.stateProvider.get(AUTH_REQUEST_PUSH_NOTIFICATION_KEY);
        this.currentAuthType$ = this.loginStrategyCacheService.currentAuthType$;
        this.loginStrategy$ = this.loginStrategyCacheService.currentAuthType$.pipe((0,external_rxjs_namespaceObject.distinctUntilChanged)(), (0,external_rxjs_namespaceObject.combineLatestWith)(this.loginStrategyCacheService.cacheData$), this.initializeLoginStrategy.bind(this), (0,external_rxjs_namespaceObject.shareReplay)({ refCount: true, bufferSize: 1 }));
    }
    getEmail() {
        return login_strategy_service_awaiter(this, void 0, void 0, function* () {
            const strategy = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.loginStrategy$);
            if (strategy && "email$" in strategy) {
                return yield (0,external_rxjs_namespaceObject.firstValueFrom)(strategy.email$);
            }
            return null;
        });
    }
    getMasterPasswordHash() {
        return login_strategy_service_awaiter(this, void 0, void 0, function* () {
            const strategy = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.loginStrategy$);
            if (strategy && "serverMasterKeyHash$" in strategy) {
                return yield (0,external_rxjs_namespaceObject.firstValueFrom)(strategy.serverMasterKeyHash$);
            }
            return null;
        });
    }
    getSsoEmail2FaSessionToken() {
        return login_strategy_service_awaiter(this, void 0, void 0, function* () {
            const strategy = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.loginStrategy$);
            if (strategy && "ssoEmail2FaSessionToken$" in strategy) {
                return yield (0,external_rxjs_namespaceObject.firstValueFrom)(strategy.ssoEmail2FaSessionToken$);
            }
            return null;
        });
    }
    getAccessCode() {
        return login_strategy_service_awaiter(this, void 0, void 0, function* () {
            const strategy = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.loginStrategy$);
            if (strategy && "accessCode$" in strategy) {
                return yield (0,external_rxjs_namespaceObject.firstValueFrom)(strategy.accessCode$);
            }
            return null;
        });
    }
    getAuthRequestId() {
        return login_strategy_service_awaiter(this, void 0, void 0, function* () {
            const strategy = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.loginStrategy$);
            if (strategy && "authRequestId$" in strategy) {
                return yield (0,external_rxjs_namespaceObject.firstValueFrom)(strategy.authRequestId$);
            }
            return null;
        });
    }
    logIn(credentials) {
        return login_strategy_service_awaiter(this, void 0, void 0, function* () {
            var _a;
            yield this.clearCache();
            yield this.loginStrategyCacheService.setCurrentAuthType(credentials.type);
            const strategy = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.loginStrategy$);
            // Note: We aren't passing the credentials directly to the strategy since they are
            // created in the popup and can cause DeadObject references on Firefox.
            // This is a shallow copy, but use deep copy in future if objects are added to credentials
            // that were created in popup.
            // If the popup uses its own instance of this service, this can be removed.
            const ownedCredentials = Object.assign({}, credentials);
            const result = yield (strategy === null || strategy === void 0 ? void 0 : strategy.logIn(ownedCredentials));
            if (result != null && !result.requiresTwoFactor && !result.requiresDeviceVerification) {
                yield this.clearCache();
            }
            else {
                // Cache the strategy data so we can attempt again later with 2fa or device verification
                yield this.loginStrategyCacheService.setCacheData((_a = strategy === null || strategy === void 0 ? void 0 : strategy.exportCache()) !== null && _a !== void 0 ? _a : null);
                yield this.loginStrategySessionTimeoutService.startSessionTimeout();
            }
            if (!result) {
                throw new Error("No auth result returned");
            }
            return result;
        });
    }
    logInTwoFactor(twoFactor) {
        return login_strategy_service_awaiter(this, void 0, void 0, function* () {
            if (!(yield this.isSessionValid())) {
                throw new Error(this.i18nService.t("sessionTimeout"));
            }
            const strategy = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.loginStrategy$);
            if (strategy == null) {
                throw new Error("No login strategy found.");
            }
            try {
                const result = yield strategy.logInTwoFactor(twoFactor);
                // Only clear cache if 2FA token has been accepted, otherwise we need to be able to try again
                if (result != null && !result.requiresTwoFactor) {
                    yield this.clearCache();
                }
                return result;
            }
            catch (e) {
                // API exceptions are okay, but if there are any unhandled client-side errors then clear cache to be safe
                if (!(e instanceof ErrorResponse)) {
                    yield this.clearCache();
                }
                throw e;
            }
        });
    }
    /**
     * Sends a token request to the server with the provided device verification OTP.
     * Returns an error if no session data is found or if the current login strategy does not support device verification.
     * @param deviceVerificationOtp The OTP to send to the server for device verification.
     * @returns The result of the token request.
     */
    logInNewDeviceVerification(deviceVerificationOtp) {
        return login_strategy_service_awaiter(this, void 0, void 0, function* () {
            if (!(yield this.isSessionValid())) {
                throw new Error(this.i18nService.t("sessionTimeout"));
            }
            const strategy = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.loginStrategy$);
            if (strategy == null) {
                throw new Error("No login strategy found.");
            }
            if (!("logInNewDeviceVerification" in strategy)) {
                throw new Error("Current login strategy does not support device verification.");
            }
            try {
                const result = yield strategy.logInNewDeviceVerification(deviceVerificationOtp);
                // Only clear cache if device verification succeeds
                if (result !== null && !result.requiresDeviceVerification) {
                    yield this.clearCache();
                }
                return result;
            }
            catch (e) {
                // Clear the cache if there is an unhandled client-side error
                if (!(e instanceof ErrorResponse)) {
                    yield this.clearCache();
                }
                throw e;
            }
        });
    }
    clearCache() {
        return login_strategy_service_awaiter(this, void 0, void 0, function* () {
            yield this.loginStrategyCacheService.clearCache();
            yield this.loginStrategySessionTimeoutService.cancelSessionTimeout();
        });
    }
    isSessionValid() {
        return login_strategy_service_awaiter(this, void 0, void 0, function* () {
            const cache = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.loginStrategyCacheService.cacheData$);
            if (cache == null) {
                return false;
            }
            // If the Login Strategy Cache Expiration State value is less than the current
            // datetime stamp, then the cache is invalid and should be cleared.
            const expiration = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.loginStrategyCacheService.cacheExpiration$);
            if (expiration != null && expiration < new Date()) {
                yield this.clearCache();
                return false;
            }
            return true;
        });
    }
    initializeLoginStrategy(source) {
        const sharedDeps = [
            this.accountService,
            this.masterPasswordService,
            this.keyService,
            this.encryptService,
            this.apiService,
            this.tokenService,
            this.appIdService,
            this.platformUtilsService,
            this.messagingService,
            this.logService,
            this.stateService,
            this.twoFactorService,
            this.userDecryptionOptionsService,
            this.billingAccountProfileStateService,
            this.vaultTimeoutSettingsService,
            this.kdfConfigService,
            this.environmentService,
            this.configService,
            this.accountCryptographicStateService,
        ];
        return source.pipe((0,external_rxjs_namespaceObject.map)(([strategy, data]) => {
            var _a, _b, _c, _d, _e;
            if (strategy == null) {
                return null;
            }
            switch (strategy) {
                case AuthenticationType.Password:
                    return new PasswordLoginStrategy((_a = data === null || data === void 0 ? void 0 : data.password) !== null && _a !== void 0 ? _a : new PasswordLoginStrategyData(), this.passwordStrengthService, this.policyService, this.passwordPreloginService, this.unlockService, ...sharedDeps);
                case AuthenticationType.Sso:
                    return new SsoLoginStrategy((_b = data === null || data === void 0 ? void 0 : data.sso) !== null && _b !== void 0 ? _b : new SsoLoginStrategyData(), this.keyConnectorService, this.unlockService, this.deviceTrustService, this.authRequestService, ...sharedDeps);
                case AuthenticationType.UserApiKey:
                    return new UserApiLoginStrategy((_c = data === null || data === void 0 ? void 0 : data.userApiKey) !== null && _c !== void 0 ? _c : new UserApiLoginStrategyData(), this.keyConnectorService, this.unlockService, ...sharedDeps);
                case AuthenticationType.AuthRequest:
                    return new AuthRequestLoginStrategy((_d = data === null || data === void 0 ? void 0 : data.authRequest) !== null && _d !== void 0 ? _d : new AuthRequestLoginStrategyData(), this.deviceTrustService, ...sharedDeps);
                case AuthenticationType.WebAuthn:
                    return new WebAuthnLoginStrategy((_e = data === null || data === void 0 ? void 0 : data.webAuthn) !== null && _e !== void 0 ? _e : new WebAuthnLoginStrategyData(), ...sharedDeps);
            }
        }));
    }
}

;// ../../libs/auth/src/common/services/login-strategies/default-login-strategy-cache.service.ts
var default_login_strategy_cache_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

class DefaultLoginStrategyCacheService {
    constructor(stateProvider) {
        this.stateProvider = stateProvider;
        this.currentAuthnTypeState = this.stateProvider.get(CURRENT_LOGIN_STRATEGY_KEY);
        this.loginStrategyCacheState = this.stateProvider.get(CACHE_KEY);
        this.loginStrategyCacheExpirationState = this.stateProvider.get(CACHE_EXPIRATION_KEY);
        this.currentAuthType$ = this.currentAuthnTypeState.state$;
        this.cacheData$ = this.loginStrategyCacheState.state$;
        this.cacheExpiration$ = this.loginStrategyCacheExpirationState.state$;
    }
    setCurrentAuthType(type) {
        return default_login_strategy_cache_service_awaiter(this, void 0, void 0, function* () {
            yield this.currentAuthnTypeState.update((_) => type);
        });
    }
    setCacheData(data) {
        return default_login_strategy_cache_service_awaiter(this, void 0, void 0, function* () {
            yield this.loginStrategyCacheState.update((_) => data);
        });
    }
    setCacheExpiration(date) {
        return default_login_strategy_cache_service_awaiter(this, void 0, void 0, function* () {
            yield this.loginStrategyCacheExpirationState.update((_) => date);
        });
    }
    clearCache() {
        return default_login_strategy_cache_service_awaiter(this, void 0, void 0, function* () {
            yield this.currentAuthnTypeState.update((_) => null);
            yield this.loginStrategyCacheState.update((_) => null);
            yield this.loginStrategyCacheExpirationState.update((_) => null);
        });
    }
}

;// ../../libs/messaging/src/message.listener.ts

/**
 * A class that allows for listening to messages coming through the application,
 * allows for listening of all messages or just the messages you care about.
 *
 * @note Consider NOT using messaging at all if you can. State Providers offer an observable stream of
 * data that is persisted. This can serve messages that might have been used to notify of settings changes
 * or vault data changes and those observables should be preferred over messaging.
 */
class MessageListener {
    constructor(messageStream) {
        this.messageStream = messageStream;
        /**
         * A stream of all messages sent through the application. It does not contain type information for the
         * other properties on the messages. You are encouraged to instead subscribe to an individual message
         * through {@link messages$}.
         */
        this.allMessages$ = this.messageStream;
    }
    /**
     * Creates an observable stream filtered to just the command given via the {@link CommandDefinition} and typed
     * to the generic contained in the CommandDefinition. Be careful using this method unless all your messages are being
     * sent through `MessageSender.send`, if that isn't the case you should have lower confidence in the message
     * payload being the expected type.
     *
     * @param commandDefinition The CommandDefinition containing the information about the message type you care about.
     */
    messages$(commandDefinition) {
        return this.allMessages$.pipe((0,external_rxjs_namespaceObject.filter)((msg) => (msg === null || msg === void 0 ? void 0 : msg.command) === commandDefinition.command));
    }
}
/**
 * A helper property for returning a MessageListener that will never emit any messages and will immediately complete.
 */
MessageListener.EMPTY = new MessageListener(external_rxjs_namespaceObject.EMPTY);

;// ../../libs/messaging/src/message.sender.ts
class MultiMessageSender {
    constructor(innerMessageSenders) {
        this.innerMessageSenders = innerMessageSenders;
    }
    send(commandDefinition, payload = {}) {
        for (const messageSender of this.innerMessageSenders) {
            messageSender.send(commandDefinition, payload);
        }
    }
}
class MessageSender {
    /**
     * A helper method for combine multiple {@link MessageSender}'s.
     * @param messageSenders The message senders that should be combined.
     * @returns A message sender that will relay all messages to the given message senders.
     */
    static combine(...messageSenders) {
        return new MultiMessageSender(messageSenders);
    }
}
/**
 * A helper property for creating a {@link MessageSender} that sends to nowhere.
 */
MessageSender.EMPTY = new MultiMessageSender([]);

;// ../../libs/messaging/src/types.ts
/**
 * A class for defining information about a message, this is helpful
 * alonside `MessageSender` and `MessageListener` for providing a type
 * safe(-ish) way of sending and receiving messages.
 */
class CommandDefinition {
    constructor(command) {
        this.command = command;
    }
}

;// ../../libs/messaging/src/is-external-message.ts
const is_external_message_EXTERNAL_SOURCE_TAG = Symbol("externalSource");
const isExternalMessage = (message) => {
    return (message === null || message === void 0 ? void 0 : message[is_external_message_EXTERNAL_SOURCE_TAG]) === true;
};

;// ../../libs/messaging/src/helpers.ts


const helpers_getCommand = (commandDefinition) => {
    if (typeof commandDefinition === "string") {
        return commandDefinition;
    }
    else {
        return commandDefinition.command;
    }
};
const tagAsExternal = () => {
    return map((message) => {
        return Object.assign(message, { [EXTERNAL_SOURCE_TAG]: true });
    });
};

;// ../../libs/messaging/src/subject-message.sender.ts

class SubjectMessageSender {
    constructor(messagesSubject) {
        this.messagesSubject = messagesSubject;
    }
    send(commandDefinition, payload = {}) {
        const command = getCommand(commandDefinition);
        this.messagesSubject.next(Object.assign(payload !== null && payload !== void 0 ? payload : {}, { command: command }));
    }
}

;// ../../libs/messaging/src/index.ts




// Internal implementations



;// ../../libs/common/src/platform/messaging/index.ts


;// ../../libs/auth/src/common/services/login-strategies/default-login-strategy-session-timeout.service.ts
var default_login_strategy_session_timeout_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};



const LOGIN_SESSION_TIMEOUT_LENGTH = 5 * 60 * 1000; // 5 minutes
const LOGIN_SESSION_EXPIRED = new CommandDefinition("loginSessionExpired");
class DefaultLoginStrategySessionTimeoutService {
    constructor(taskSchedulerService, loginStrategyCacheService, logService, messageSender, messageListener) {
        this.taskSchedulerService = taskSchedulerService;
        this.loginStrategyCacheService = loginStrategyCacheService;
        this.logService = logService;
        this.messageSender = messageSender;
        this.messageListener = messageListener;
        this.loginSessionTimeout$ = this.messageListener
            .messages$(LOGIN_SESSION_EXPIRED)
            .pipe((0,external_rxjs_namespaceObject.map)(() => undefined));
        this.taskSchedulerService.registerTaskHandler(ScheduledTaskNames.loginStrategySessionTimeout, () => default_login_strategy_session_timeout_service_awaiter(this, void 0, void 0, function* () {
            try {
                this.messageSender.send(LOGIN_SESSION_EXPIRED, {});
            }
            catch (e) {
                this.logService.error("Failed to send login session expired message", e);
            }
            try {
                yield this.loginStrategyCacheService.clearCache();
            }
            catch (e) {
                this.logService.error("Failed to clear cache during session timeout", e);
            }
        }));
    }
    startSessionTimeout() {
        return default_login_strategy_session_timeout_service_awaiter(this, void 0, void 0, function* () {
            yield this.cancelSessionTimeout();
            yield this.loginStrategyCacheService.setCacheExpiration(new Date(Date.now() + LOGIN_SESSION_TIMEOUT_LENGTH));
            this.sessionTimeoutSubscription = this.taskSchedulerService.setTimeout(ScheduledTaskNames.loginStrategySessionTimeout, LOGIN_SESSION_TIMEOUT_LENGTH);
        });
    }
    cancelSessionTimeout() {
        return default_login_strategy_session_timeout_service_awaiter(this, void 0, void 0, function* () {
            var _a;
            yield this.loginStrategyCacheService.setCacheExpiration(null);
            (_a = this.sessionTimeoutSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
        });
    }
}

;// ../../libs/auth/src/common/services/user-decryption-options/user-decryption-options.service.ts
var user_decryption_options_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};



const user_decryption_options_service_USER_DECRYPTION_OPTIONS = new UserKeyDefinition(USER_DECRYPTION_OPTIONS_DISK, "decryptionOptions", {
    deserializer: (decryptionOptions) => UserDecryptionOptions.fromJSON(decryptionOptions),
    clearOn: ["logout"],
});
class UserDecryptionOptionsService {
    constructor(singleUserStateProvider) {
        this.singleUserStateProvider = singleUserStateProvider;
    }
    userDecryptionOptionsById$(userId) {
        return this.singleUserStateProvider
            .get(userId, user_decryption_options_service_USER_DECRYPTION_OPTIONS)
            .state$.pipe((0,external_rxjs_namespaceObject.filter)((options) => options != null));
    }
    hasMasterPasswordById$(userId) {
        return this.userDecryptionOptionsById$(userId).pipe((0,external_rxjs_namespaceObject.map)((options) => { var _a; return (_a = options.hasMasterPassword) !== null && _a !== void 0 ? _a : false; }));
    }
    setUserDecryptionOptionsById(userId, userDecryptionOptions) {
        return user_decryption_options_service_awaiter(this, void 0, void 0, function* () {
            yield this.singleUserStateProvider
                .get(userId, user_decryption_options_service_USER_DECRYPTION_OPTIONS)
                .update((_) => userDecryptionOptions);
        });
    }
}

;// ../../libs/common/src/auth/models/domain/admin-auth-req-storable.ts

class AdminAuthRequestStorable {
    constructor(init) {
        if (init) {
            Object.assign(this, init);
        }
    }
    toJSON() {
        return {
            id: this.id,
            privateKey: utils_Utils.fromArrayToByteString(this.privateKey),
        };
    }
    static fromJSON(obj) {
        if (obj == null) {
            return null;
        }
        let privateKeyBuffer = null;
        if (obj.privateKey) {
            privateKeyBuffer = utils_Utils.fromByteStringToArray(obj.privateKey);
        }
        return new AdminAuthRequestStorable({
            id: obj.id,
            privateKey: privateKeyBuffer,
        });
    }
}

;// ../../libs/common/src/auth/models/request/passwordless-auth.request.ts
class PasswordlessAuthRequest {
    constructor(key, masterPasswordHash, deviceIdentifier, requestApproved) {
        this.key = key;
        this.masterPasswordHash = masterPasswordHash;
        this.deviceIdentifier = deviceIdentifier;
        this.requestApproved = requestApproved;
    }
}

;// ../../libs/common/src/auth/models/response/auth-request.response.ts

const RequestTimeOut = 60000 * 15; //15 Minutes
class AuthRequestResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.id = this.getResponseProperty("Id");
        this.publicKey = this.getResponseProperty("PublicKey");
        this.requestDeviceType = this.getResponseProperty("RequestDeviceType");
        this.requestDeviceTypeValue = this.getResponseProperty("RequestDeviceTypeValue");
        this.requestDeviceIdentifier = this.getResponseProperty("RequestDeviceIdentifier");
        this.requestIpAddress = this.getResponseProperty("RequestIpAddress");
        this.requestCountryName = this.getResponseProperty("RequestCountryName");
        this.key = this.getResponseProperty("Key");
        this.creationDate = this.getResponseProperty("CreationDate");
        this.requestApproved = this.getResponseProperty("RequestApproved");
        this.responseDate = this.getResponseProperty("ResponseDate");
        this.deviceId = this.getResponseProperty("RequestDeviceId");
        const requestDate = new Date(this.creationDate);
        const requestDateUTC = Date.UTC(requestDate.getUTCFullYear(), requestDate.getUTCMonth(), requestDate.getDate(), requestDate.getUTCHours(), requestDate.getUTCMinutes(), requestDate.getUTCSeconds(), requestDate.getUTCMilliseconds());
        const dateNow = new Date(Date.now());
        const dateNowUTC = Date.UTC(dateNow.getUTCFullYear(), dateNow.getUTCMonth(), dateNow.getDate(), dateNow.getUTCHours(), dateNow.getUTCMinutes(), dateNow.getUTCSeconds(), dateNow.getUTCMilliseconds());
        this.isExpired = dateNowUTC - requestDateUTC >= RequestTimeOut;
        this.isAnswered = this.requestApproved != null && this.responseDate != null;
    }
}

;// ../../libs/auth/src/common/services/auth-request/auth-request.service.ts
var auth_request_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore








/**
 * Disk-local to maintain consistency between tabs. We don't want to
 * clear this on logout since admin auth requests are long-lived.
 */
const auth_request_service_ADMIN_AUTH_REQUEST_KEY = new UserKeyDefinition(AUTH_REQUEST_DISK_LOCAL, "adminAuthRequest", {
    deserializer: (value) => value,
    clearOn: [],
});
class AuthRequestService {
    constructor(appIdService, masterPasswordService, keyService, encryptService, apiService, stateProvider, authRequestApiService, accountService) {
        this.appIdService = appIdService;
        this.masterPasswordService = masterPasswordService;
        this.keyService = keyService;
        this.encryptService = encryptService;
        this.apiService = apiService;
        this.stateProvider = stateProvider;
        this.authRequestApiService = authRequestApiService;
        this.accountService = accountService;
        this.authRequestPushNotificationSubject = new external_rxjs_namespaceObject.Subject();
        // Observable emission is used to trigger a toast in consuming components
        this.adminLoginApprovedSubject = new external_rxjs_namespaceObject.Subject();
        this.authRequestPushNotification$ = this.authRequestPushNotificationSubject.asObservable();
        this.adminLoginApproved$ = this.adminLoginApprovedSubject.asObservable();
    }
    getAdminAuthRequest(userId) {
        return auth_request_service_awaiter(this, void 0, void 0, function* () {
            if (userId == null) {
                throw new Error("User ID is required");
            }
            const authRequestSerialized = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.stateProvider.getUser(userId, auth_request_service_ADMIN_AUTH_REQUEST_KEY).state$);
            const adminAuthRequestStorable = AdminAuthRequestStorable.fromJSON(authRequestSerialized);
            return adminAuthRequestStorable;
        });
    }
    setAdminAuthRequest(authRequest, userId) {
        return auth_request_service_awaiter(this, void 0, void 0, function* () {
            if (userId == null) {
                throw new Error("User ID is required");
            }
            if (authRequest == null) {
                throw new Error("Auth request is required");
            }
            yield this.stateProvider.setUserState(auth_request_service_ADMIN_AUTH_REQUEST_KEY, authRequest.toJSON(), userId);
        });
    }
    clearAdminAuthRequest(userId) {
        return auth_request_service_awaiter(this, void 0, void 0, function* () {
            if (userId == null) {
                throw new Error("User ID is required");
            }
            yield this.stateProvider.setUserState(auth_request_service_ADMIN_AUTH_REQUEST_KEY, null, userId);
        });
    }
    /**
     * @description Gets the list of all standard (not admin approval) pending AuthRequests.
     */
    getPendingAuthRequests$() {
        return (0,external_rxjs_namespaceObject.defer)(() => this.authRequestApiService.getPendingAuthRequests()).pipe((0,external_rxjs_namespaceObject.map)((authRequestResponses) => {
            return authRequestResponses.data.map((authRequestResponse) => {
                return new AuthRequestResponse(authRequestResponse);
            });
        }));
    }
    getLatestPendingAuthRequest$() {
        return this.getPendingAuthRequests$().pipe((0,external_rxjs_namespaceObject.map)((authRequests) => {
            if (authRequests.length === 0) {
                return null;
            }
            return authRequests.sort((a, b) => {
                const dateA = new Date(a.creationDate).getTime();
                const dateB = new Date(b.creationDate).getTime();
                return dateB - dateA; // Sort in descending order
            })[0];
        }));
    }
    approveOrDenyAuthRequest(approve, authRequest) {
        return auth_request_service_awaiter(this, void 0, void 0, function* () {
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
            if (!authRequest.id) {
                throw new Error("Auth request has no id");
            }
            if (!authRequest.publicKey) {
                throw new Error("Auth request has no public key");
            }
            if (activeUserId == null) {
                throw new Error("User ID is required");
            }
            const pubKey = utils_Utils.fromB64ToArray(authRequest.publicKey);
            const keyToEncrypt = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.userKey$(activeUserId));
            const encryptedKey = yield this.encryptService.encapsulateKeyUnsigned(keyToEncrypt, pubKey);
            const response = new PasswordlessAuthRequest(encryptedKey.encryptedString, undefined, yield this.appIdService.getAppId(), approve);
            return yield this.apiService.putAuthRequest(authRequest.id, response);
        });
    }
    setUserKeyAfterDecryptingSharedUserKey(authReqResponse, authReqPrivateKey, userId) {
        return auth_request_service_awaiter(this, void 0, void 0, function* () {
            const userKey = yield this.decryptPubKeyEncryptedUserKey(authReqResponse.key, authReqPrivateKey);
            yield this.keyService.setUserKey(userKey, userId);
        });
    }
    // Decryption helpers
    decryptPubKeyEncryptedUserKey(pubKeyEncryptedUserKey, privateKey) {
        return auth_request_service_awaiter(this, void 0, void 0, function* () {
            const decryptedUserKey = yield this.encryptService.decapsulateKeyUnsigned(new enc_string_EncString(pubKeyEncryptedUserKey), privateKey);
            return decryptedUserKey;
        });
    }
    sendAuthRequestPushNotification(notification) {
        if (notification.id != null) {
            this.authRequestPushNotificationSubject.next(notification.id);
        }
    }
    getFingerprintPhrase(email, publicKey) {
        return auth_request_service_awaiter(this, void 0, void 0, function* () {
            return (yield this.keyService.getFingerprint(email.toLowerCase(), publicKey)).join("-");
        });
    }
    emitAdminLoginApproved() {
        this.adminLoginApprovedSubject.next();
    }
}

;// ../../libs/common/src/models/response/list.response.ts

class ListResponse extends BaseResponse {
    constructor(response, t) {
        super(response);
        const data = this.getResponseProperty("Data");
        this.data = data == null ? [] : data.map((dr) => new t(dr));
        this.continuationToken = this.getResponseProperty("ContinuationToken");
    }
}

;// ../../libs/auth/src/common/services/auth-request/auth-request-api.service.ts
var auth_request_api_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};


class DefaultAuthRequestApiService {
    constructor(apiService, logService) {
        this.apiService = apiService;
        this.logService = logService;
    }
    getPendingAuthRequests() {
        return auth_request_api_service_awaiter(this, void 0, void 0, function* () {
            const path = `/auth-requests/pending`;
            const r = yield this.apiService.send("GET", path, null, true, true);
            return new ListResponse(r, AuthRequestResponse);
        });
    }
    getAuthRequest(requestId) {
        return auth_request_api_service_awaiter(this, void 0, void 0, function* () {
            try {
                const path = `/auth-requests/${requestId}`;
                const response = yield this.apiService.send("GET", path, null, true, true);
                return new AuthRequestResponse(response);
            }
            catch (e) {
                this.logService.error(e);
                throw e;
            }
        });
    }
    getAuthResponse(requestId, accessCode) {
        return auth_request_api_service_awaiter(this, void 0, void 0, function* () {
            try {
                const path = `/auth-requests/${requestId}/response?code=${accessCode}`;
                const response = yield this.apiService.send("GET", path, null, false, true);
                return new AuthRequestResponse(response);
            }
            catch (e) {
                this.logService.error(e);
                throw e;
            }
        });
    }
    postAdminAuthRequest(request) {
        return auth_request_api_service_awaiter(this, void 0, void 0, function* () {
            try {
                const response = yield this.apiService.send("POST", "/auth-requests/admin-request", request, true, true);
                return new AuthRequestResponse(response);
            }
            catch (e) {
                this.logService.error(e);
                throw e;
            }
        });
    }
    postAuthRequest(request) {
        return auth_request_api_service_awaiter(this, void 0, void 0, function* () {
            try {
                // Submit the current device identifier in the header as well as in the POST body.
                // The value in the header will be used to build the request context and ensure that the resulting
                // server notifications have the current device as a source.
                const response = yield this.apiService.send("POST", "/auth-requests/", request, false, true, null, (headers) => {
                    headers.set("Device-Identifier", request.deviceIdentifier);
                });
                return new AuthRequestResponse(response);
            }
            catch (e) {
                this.logService.error(e);
                throw e;
            }
        });
    }
}

;// ../../libs/auth/src/common/services/accounts/lock.service.ts
var lock_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};



class LockService {
}
class DefaultLockService {
    constructor(accountService, biometricService, vaultTimeoutSettingsService, logoutService, messagingService, searchService, folderService, masterPasswordService, stateEventRunnerService, cipherService, authService, systemService, processReloadService, logService, keyService) {
        this.accountService = accountService;
        this.biometricService = biometricService;
        this.vaultTimeoutSettingsService = vaultTimeoutSettingsService;
        this.logoutService = logoutService;
        this.messagingService = messagingService;
        this.searchService = searchService;
        this.folderService = folderService;
        this.masterPasswordService = masterPasswordService;
        this.stateEventRunnerService = stateEventRunnerService;
        this.cipherService = cipherService;
        this.authService = authService;
        this.systemService = systemService;
        this.processReloadService = processReloadService;
        this.logService = logService;
        this.keyService = keyService;
    }
    lockAll() {
        return lock_service_awaiter(this, void 0, void 0, function* () {
            const accounts = yield (0,external_rxjs_namespaceObject.firstValueFrom)((0,external_rxjs_namespaceObject.combineLatest)([this.accountService.activeAccount$, this.accountService.accounts$]).pipe((0,external_rxjs_namespaceObject.map)(([activeAccount, accounts]) => {
                const otherAccounts = Object.keys(accounts);
                if (activeAccount == null) {
                    return { activeAccount: null, otherAccounts: otherAccounts };
                }
                return {
                    activeAccount: activeAccount.id,
                    otherAccounts: otherAccounts.filter((accountId) => accountId !== activeAccount.id),
                };
            })));
            for (const otherAccount of accounts.otherAccounts) {
                yield this.lock(otherAccount);
            }
            // Do the active account last in case we ever try to route the user on lock
            // that way this whole operation will be complete before that routing
            // could take place.
            if (accounts.activeAccount != null) {
                yield this.lock(accounts.activeAccount);
            }
        });
    }
    lock(userId) {
        return lock_service_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(userId, "userId", "LockService");
            this.logService.info(`[LockService] Locking user ${userId}`);
            // If user already logged out, then skip locking
            if ((yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.authService.authStatusFor$(userId))) ===
                authentication_status_AuthenticationStatus.LoggedOut) {
                return;
            }
            // If user cannot lock, then logout instead
            if (!(yield this.vaultTimeoutSettingsService.canLock(userId))) {
                // Logout should perform the same steps
                yield this.logoutService.logout(userId, "vaultTimeout");
                this.logService.info(`[LockService] User ${userId} cannot lock, logging out instead.`);
                return;
            }
            yield this.wipeDecryptedState(userId);
            yield this.waitForLockedStatus(userId);
            yield this.systemService.clearPendingClipboard();
            yield this.runPlatformOnLockActions();
            this.logService.info(`[LockService] Locked user ${userId}`);
            // Subscribers navigate the client to the lock screen based on this lock message.
            // We need to disable auto-prompting as we are just entering a locked state now.
            yield this.biometricService.setShouldAutopromptNow(false);
            this.messagingService.send("locked", { userId });
            // Wipe the current process to clear active secrets in memory.
            yield this.processReloadService.startProcessReload();
        });
    }
    wipeDecryptedState(userId) {
        return lock_service_awaiter(this, void 0, void 0, function* () {
            // Manually clear state
            yield this.searchService.clearIndex(userId);
            //! DO NOT REMOVE folderService.clearDecryptedFolderState ! For more information see PM-25660
            yield this.folderService.clearDecryptedFolderState(userId);
            yield this.cipherService.clearCache(userId);
            // Clear CLI unlock state
            yield this.keyService.clearStoredUserKey(userId);
            // This will clear ephemeral state such as the user's user key based on the key definition's clear-on
            yield this.stateEventRunnerService.handleEvent("lock", userId);
        });
    }
    waitForLockedStatus(userId) {
        return lock_service_awaiter(this, void 0, void 0, function* () {
            // HACK: Start listening for the transition of the locking user from something to the locked state.
            // This is very much a hack to ensure that the authentication status to retrievable right after
            // it does its work. Particularly and `"locked"` message. Instead the message should be deprecated
            // and people should subscribe and react to `authStatusFor$` themselves.
            yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.authService.authStatusFor$(userId).pipe((0,external_rxjs_namespaceObject.filter)((authStatus) => authStatus === authentication_status_AuthenticationStatus.Locked), (0,external_rxjs_namespaceObject.timeout)({
                first: 5000,
                with: () => {
                    throw new Error("The lock process did not complete in a reasonable amount of time.");
                },
            })));
        });
    }
    runPlatformOnLockActions() {
        return lock_service_awaiter(this, void 0, void 0, function* () {
            // No platform specific actions to run for this platform.
            return;
        });
    }
}

;// ../../libs/auth/src/common/services/login-success-handler/default-login-success-handler.service.ts
var default_login_success_handler_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
class DefaultLoginSuccessHandlerService {
    constructor(configService, loginEmailService, ssoLoginService, syncService, userAsymmetricKeysRegenerationService, encryptedMigrator, logService) {
        this.configService = configService;
        this.loginEmailService = loginEmailService;
        this.ssoLoginService = ssoLoginService;
        this.syncService = syncService;
        this.userAsymmetricKeysRegenerationService = userAsymmetricKeysRegenerationService;
        this.encryptedMigrator = encryptedMigrator;
        this.logService = logService;
    }
    run(userId, masterPassword) {
        return default_login_success_handler_service_awaiter(this, void 0, void 0, function* () {
            yield this.syncService.fullSync(true, { skipTokenRefresh: true });
            yield this.userAsymmetricKeysRegenerationService.regenerateIfNeeded(userId);
            yield this.loginEmailService.clearLoginEmail();
            try {
                yield this.encryptedMigrator.runMigrations(userId, masterPassword);
            }
            catch (_a) {
                // Don't block login success on migration failure
            }
            const ssoLoginEmail = yield this.ssoLoginService.getSsoEmail();
            if (!ssoLoginEmail) {
                this.logService.debug("SSO login email not found.");
                return;
            }
            yield this.ssoLoginService.updateSsoRequiredCache(ssoLoginEmail, userId);
            yield this.ssoLoginService.clearSsoEmail();
        });
    }
}

;// ../../libs/auth/src/common/services/sso-redirect/sso-url.service.ts
const DESKTOP_SSO_CALLBACK = "bitwarden://sso-callback";
class SsoUrlService {
    /**
     * Builds a URL for redirecting users to the web app SSO component to complete SSO
     * @param webAppUrl The URL of the web app
     * @param clientType The client type that is initiating SSO, which will drive how the response is handled
     * @param redirectUri The redirect URI or callback that will receive the SSO code after authentication
     * @param state A state value that will be persisted through the SSO flow
     * @param codeChallenge A challenge value that will be used to verify the SSO code after authentication
     * @param email The optional email address of the user initiating SSO, which will be used to look up the org SSO identifier
     * @param orgSsoIdentifier The optional SSO identifier of the org that is initiating SSO
     * @returns The URL for redirecting users to the web app SSO component
     */
    buildSsoUrl(webAppUrl, clientType, redirectUri, state, codeChallenge, email, orgSsoIdentifier) {
        let url = webAppUrl +
            "/#/sso?clientId=" +
            clientType +
            "&redirectUri=" +
            encodeURIComponent(redirectUri) +
            "&state=" +
            state +
            "&codeChallenge=" +
            codeChallenge;
        if (email) {
            url += "&email=" + encodeURIComponent(email);
        }
        if (orgSsoIdentifier) {
            url += "&identifier=" + encodeURIComponent(orgSsoIdentifier);
        }
        return url;
    }
}

;// ../../libs/auth/src/common/services/logout/default-logout.service.ts
var default_logout_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
class DefaultLogoutService {
    constructor(messagingService) {
        this.messagingService = messagingService;
    }
    logout(userId, logoutReason) {
        return default_logout_service_awaiter(this, void 0, void 0, function* () {
            this.messagingService.send("logout", { userId, logoutReason });
            return undefined;
        });
    }
}

;// ../../libs/auth/src/common/services/index.ts












;// ../../libs/auth/src/common/utilities/decode-jwt-token-to-json.utility.ts

function decodeJwtTokenToJson(jwtToken) {
    if (jwtToken == null) {
        throw new Error("JWT token not found");
    }
    const parts = jwtToken.split(".");
    if (parts.length !== 3) {
        throw new Error("JWT must have 3 parts");
    }
    // JWT has 3 parts: header, payload, signature separated by '.'
    // So, grab the payload to decode
    const encodedPayload = parts[1];
    let decodedPayloadJSON;
    try {
        // Attempt to decode from URL-safe Base64 to UTF-8
        decodedPayloadJSON = utils_Utils.fromUrlB64ToUtf8(encodedPayload);
        // FIXME: Remove when updating file. Eslint update
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
    }
    catch (decodingError) {
        throw new Error("Cannot decode the token");
    }
    try {
        // Attempt to parse the JSON payload
        const decodedToken = JSON.parse(decodedPayloadJSON);
        return decodedToken;
        // FIXME: Remove when updating file. Eslint update
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
    }
    catch (jsonError) {
        throw new Error("Cannot parse the token's payload into JSON");
    }
}

;// ../../libs/auth/src/common/utilities/index.ts


;// ../../libs/auth/src/common/login-strategies/index.ts


;// ../../libs/auth/src/common/index.ts
/**
 * This barrel file should only contain non-Angular exports
 */







;// ../../libs/common/src/auth/models/request/secret-verification.request.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
class SecretVerificationRequest {
    /**
     * Mutates this request to include the master password authentication data, to authenticate the request.
     */
    authenticateWith(masterPasswordAuthenticationData) {
        this.masterPasswordHash = masterPasswordAuthenticationData.masterPasswordAuthenticationHash;
        return this;
    }
}

;// ../../libs/common/src/auth/models/request/two-factor-email.request.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

class TwoFactorEmailRequest extends SecretVerificationRequest {
}

;// external "fs"
const external_fs_namespaceObject = require("fs");
;// external "readline"
const external_readline_namespaceObject = require("readline");
;// ../../libs/node/src/node-utils.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore



class NodeUtils {
    static mkdirpSync(targetDir, mode = "700", relative = false, relativeDir = null) {
        const initialDir = external_path_namespaceObject.isAbsolute(targetDir) ? external_path_namespaceObject.sep : "";
        const baseDir = relative ? (relativeDir != null ? relativeDir : __dirname) : ".";
        targetDir.split(external_path_namespaceObject.sep).reduce((parentDir, childDir) => {
            const dir = external_path_namespaceObject.resolve(baseDir, parentDir, childDir);
            if (!external_fs_namespaceObject.existsSync(dir)) {
                external_fs_namespaceObject.mkdirSync(dir, mode);
            }
            return dir;
        }, initialDir);
    }
    static readFirstLine(fileName) {
        return new Promise((resolve, reject) => {
            const readStream = external_fs_namespaceObject.createReadStream(fileName, { encoding: "utf8" });
            const readInterface = external_readline_namespaceObject.createInterface(readStream);
            readInterface
                .on("line", (line) => {
                readStream.close();
                resolve(line);
            })
                .on("error", (err) => reject(err));
        });
    }
    // https://stackoverflow.com/a/31394257
    static bufferToArrayBuffer(buf) {
        return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
    }
}

;// ./src/key-management/confirm-key-connector-domain.command.ts
var confirm_key_connector_domain_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};



class ConfirmKeyConnectorDomainCommand {
    constructor(userId, keyConnectorUrl, keyConnectorService, logout, i18nService) {
        this.userId = userId;
        this.keyConnectorUrl = keyConnectorUrl;
        this.keyConnectorService = keyConnectorService;
        this.logout = logout;
        this.i18nService = i18nService;
    }
    run() {
        return confirm_key_connector_domain_command_awaiter(this, void 0, void 0, function* () {
            // If no interaction available, alert user to use web vault
            const canInteract = process.env.BW_NOINTERACTION !== "true";
            if (!canInteract) {
                yield this.logout();
                return response_Response.error(new MessageResponse(this.i18nService.t("organizationUsingKeyConnectorConfirmLoggedOut"), null));
            }
            const answer = yield external_inquirer_namespaceObject.createPromptModule({ output: process.stderr })({
                type: "list",
                name: "confirm",
                message: this.i18nService.t("confirmKeyConnectorDomain", this.keyConnectorUrl),
                choices: [
                    {
                        name: this.i18nService.t("confirm"),
                        value: "confirmed",
                    },
                    {
                        name: this.i18nService.t("logOut"),
                        value: "cancel",
                    },
                ],
            });
            if (answer.confirm === "confirmed") {
                try {
                    yield this.keyConnectorService.convertNewSsoUserToKeyConnector(this.userId);
                }
                catch (e) {
                    yield this.logout();
                    throw e;
                }
                return response_Response.success();
            }
            else {
                yield this.logout();
                return response_Response.error(this.i18nService.t("youHaveBeenLoggedOut"));
            }
        });
    }
}

;// external "jszip"
const external_jszip_namespaceObject = require("jszip");
;// ./src/utils.ts
var utils_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore









class CliUtils {
    static writeLn(s, finalLine = false, error = false) {
        const stream = error ? process.stderr : process.stdout;
        if (finalLine && (process.platform === "win32" || !stream.isTTY)) {
            stream.write(s);
        }
        else {
            stream.write(s + "\n");
        }
    }
    static readFile(input) {
        return new Promise((resolve, reject) => {
            let p = null;
            if (input != null && input !== "") {
                const osInput = external_path_namespaceObject.join(input);
                if (osInput.indexOf(external_path_namespaceObject.sep) === -1) {
                    p = external_path_namespaceObject.join(process.cwd(), osInput);
                }
                else {
                    p = osInput;
                }
            }
            else {
                reject("You must specify a file path.");
            }
            external_fs_namespaceObject.readFile(p, "utf8", (err, data) => {
                if (err != null) {
                    reject(err.message);
                }
                resolve(data);
            });
        });
    }
    static extractZipContent(input, filepath) {
        return new Promise((resolve, reject) => {
            let p = null;
            if (input != null && input !== "") {
                const osInput = external_path_namespaceObject.join(input);
                if (osInput.indexOf(external_path_namespaceObject.sep) === -1) {
                    p = external_path_namespaceObject.join(process.cwd(), osInput);
                }
                else {
                    p = osInput;
                }
            }
            else {
                reject("You must specify a file path.");
            }
            external_fs_namespaceObject.readFile(p, function (err, data) {
                if (err) {
                    reject(err);
                }
                external_jszip_namespaceObject.loadAsync(data).then((zip) => {
                    resolve(zip.file(filepath).async("string"));
                }, (reason) => {
                    reject(reason);
                });
            });
        });
    }
    /**
     * Save the given data to a file and determine the target file if necessary.
     * If output is non-empty, it is used as target filename. Otherwise the target filename is
     * built from the current working directory and the given defaultFileName.
     *
     * @param data to be written to the file.
     * @param output file to write to or empty to choose automatically.
     * @param defaultFileName to use when no explicit output filename is given.
     * @return the chosen output file.
     */
    static saveFile(data, output, defaultFileName) {
        let p = null;
        let mkdir = false;
        if (output != null && output !== "") {
            const osOutput = external_path_namespaceObject.join(output);
            if (osOutput.indexOf(external_path_namespaceObject.sep) === -1) {
                p = external_path_namespaceObject.join(process.cwd(), osOutput);
            }
            else {
                mkdir = true;
                if (osOutput.endsWith(external_path_namespaceObject.sep)) {
                    p = external_path_namespaceObject.join(osOutput, defaultFileName);
                }
                else {
                    p = osOutput;
                }
            }
        }
        else {
            p = external_path_namespaceObject.join(process.cwd(), defaultFileName);
        }
        p = external_path_namespaceObject.resolve(p);
        if (mkdir) {
            const dir = p.substring(0, p.lastIndexOf(external_path_namespaceObject.sep));
            if (!external_fs_namespaceObject.existsSync(dir)) {
                NodeUtils.mkdirpSync(dir, "700");
            }
        }
        return new Promise((resolve, reject) => {
            external_fs_namespaceObject.writeFile(p, data, { encoding: "utf8", mode: 0o600 }, (err) => {
                if (err != null) {
                    reject("Cannot save file to " + p);
                }
                resolve(p);
            });
        });
    }
    /**
     * Process the given data and write it to a file if possible. If the user requested RAW output and
     * no output name is given, the file is directly written to stdout. The resulting Response contains
     * an otherwise empty message then to prevent writing other information to stdout.
     *
     * If an output is given or no RAW output is requested, the rules from [saveFile] apply.
     *
     * @param data to be written to the file or stdout.
     * @param output file to write to or empty to choose automatically.
     * @param defaultFileName to use when no explicit output filename is given.
     * @return an empty [Response] if written to stdout or a [Response] with the chosen output file otherwise.
     */
    static saveResultToFile(data, output, defaultFileName) {
        return utils_awaiter(this, void 0, void 0, function* () {
            if ((output == null || output === "") && process.env.BW_RAW === "true") {
                // No output is given and the user expects raw output. Since the command result is about content,
                // we directly return the command result to stdout (and suppress further messages).
                process.stdout.write(data);
                return response_Response.success();
            }
            const filePath = yield this.saveFile(data, output, defaultFileName);
            const res = new MessageResponse("Saved " + filePath, null);
            res.raw = filePath;
            return response_Response.success(res);
        });
    }
    static readStdin() {
        return new Promise((resolve, reject) => {
            let input = "";
            if (process.stdin.isTTY) {
                resolve(input);
                return;
            }
            process.stdin.setEncoding("utf8");
            process.stdin.on("readable", () => {
                while (true) {
                    const chunk = process.stdin.read();
                    if (chunk == null) {
                        break;
                    }
                    input += chunk;
                }
            });
            process.stdin.on("end", () => {
                resolve(input);
            });
        });
    }
    static searchFolders(folders, search) {
        search = search.toLowerCase();
        return folders.filter((f) => {
            if (f.name != null && f.name.toLowerCase().indexOf(search) > -1) {
                return true;
            }
            return false;
        });
    }
    static searchCollections(collections, search) {
        search = search.toLowerCase();
        return collections.filter((c) => {
            if (c.name != null && c.name.toLowerCase().indexOf(search) > -1) {
                return true;
            }
            return false;
        });
    }
    static searchOrganizations(organizations, search) {
        search = search.toLowerCase();
        return organizations.filter((o) => {
            if (o.name != null && o.name.toLowerCase().indexOf(search) > -1) {
                return true;
            }
            return false;
        });
    }
    /**
     * Gets a password from all available sources. In order of priority these are:
     *   * passwordfile
     *   * passwordenv
     *   * user interaction
     *
     * Returns password string if successful, Response if not.
     */
    static getPassword(password, options, logService) {
        return utils_awaiter(this, void 0, void 0, function* () {
            if (utils_Utils.isNullOrEmpty(password)) {
                if (options === null || options === void 0 ? void 0 : options.passwordFile) {
                    password = yield NodeUtils.readFirstLine(options.passwordFile);
                }
                else if (options === null || options === void 0 ? void 0 : options.passwordEnv) {
                    if (process.env[options.passwordEnv]) {
                        password = process.env[options.passwordEnv];
                    }
                    else if (logService) {
                        logService.warning(`Warning: Provided passwordenv ${options.passwordEnv} is not set`);
                    }
                }
            }
            if (utils_Utils.isNullOrEmpty(password)) {
                if (process.env.BW_NOINTERACTION !== "true") {
                    const answer = yield external_inquirer_namespaceObject.createPromptModule({
                        output: process.stderr,
                    })({
                        type: "password",
                        name: "password",
                        message: "Master password:",
                    });
                    password = answer.password;
                }
                else {
                    return response_Response.badRequest("Master password is required. Try again in interactive mode or provide a password file or environment variable.");
                }
            }
            return password;
        });
    }
    static convertBooleanOption(optionValue) {
        return optionValue || optionValue === "" ? true : false;
    }
    static convertNumberOption(optionValue, defaultValue) {
        try {
            if (optionValue != null) {
                const numVal = parseInt(optionValue);
                return !Number.isNaN(numVal) ? numVal : defaultValue;
            }
            return defaultValue;
        }
        catch (_a) {
            return defaultValue;
        }
    }
    static convertStringOption(optionValue, defaultValue) {
        return optionValue != null ? String(optionValue) : defaultValue;
    }
}
/**
 * Like `firstValueFrom`, but returns `null` instead of throwing if the observable
 * doesn't emit within `timeoutMs` milliseconds. Useful for waiting on hot observables
 * that may lag behind state writes.
 */
function firstValueFromOrNull(observable_1) {
    return utils_awaiter(this, arguments, void 0, function* (observable, timeoutMs = 5000) {
        return (0,external_rxjs_namespaceObject.firstValueFrom)(observable.pipe((0,external_rxjs_namespaceObject.timeout)({ first: timeoutMs, with: () => (0,external_rxjs_namespaceObject.of)(null) })));
    });
}

;// ./src/auth/commands/login.command.ts
var login_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

















class LoginCommand {
    constructor(loginStrategyService, authService, twoFactorApiService, cryptoFunctionService, environmentService, passwordGenerationService, platformUtilsService, accountService, twoFactorService, syncService, keyConnectorService, logoutCallback, ssoUrlService, i18nService, masterPasswordService, userDecryptionOptionsService, encryptedMigrator) {
        this.loginStrategyService = loginStrategyService;
        this.authService = authService;
        this.twoFactorApiService = twoFactorApiService;
        this.cryptoFunctionService = cryptoFunctionService;
        this.environmentService = environmentService;
        this.passwordGenerationService = passwordGenerationService;
        this.platformUtilsService = platformUtilsService;
        this.accountService = accountService;
        this.twoFactorService = twoFactorService;
        this.syncService = syncService;
        this.keyConnectorService = keyConnectorService;
        this.logoutCallback = logoutCallback;
        this.ssoUrlService = ssoUrlService;
        this.i18nService = i18nService;
        this.masterPasswordService = masterPasswordService;
        this.userDecryptionOptionsService = userDecryptionOptionsService;
        this.encryptedMigrator = encryptedMigrator;
        this.ssoRedirectUri = null;
    }
    run(email, password, options) {
        return login_command_awaiter(this, void 0, void 0, function* () {
            var _a;
            this.options = options;
            this.email = email;
            this.canInteract = process.env.BW_NOINTERACTION !== "true";
            let ssoCodeVerifier = null;
            let ssoCode = null;
            let orgIdentifier = null;
            let clientId = null;
            let clientSecret = null;
            let selectedProvider = null;
            if (options.apikey != null) {
                const apiIdentifiers = yield this.apiIdentifiers();
                clientId = apiIdentifiers.clientId;
                clientSecret = apiIdentifiers.clientSecret;
                if (clientId == null || clientId.trim() === "") {
                    return response_Response.badRequest("client_id is required.");
                }
                if (clientSecret == null || clientSecret === "") {
                    return response_Response.badRequest("client_secret is required.");
                }
            }
            else if (options.sso != null && this.canInteract) {
                // If the optional Org SSO Identifier isn't provided, the option value is `true`.
                const orgSsoIdentifier = options.sso === true ? null : options.sso;
                const ssoPromptData = yield this.makeSsoPromptData();
                ssoCodeVerifier = ssoPromptData.ssoCodeVerifier;
                try {
                    const ssoParams = yield this.openSsoPrompt(ssoPromptData.codeChallenge, ssoPromptData.state, orgSsoIdentifier);
                    ssoCode = ssoParams.ssoCode;
                    orgIdentifier = ssoParams.orgIdentifier;
                }
                catch (_b) {
                    return response_Response.badRequest("Something went wrong. Try again.");
                }
            }
            else {
                if ((email == null || email === "") && this.canInteract) {
                    const answer = yield external_inquirer_namespaceObject.createPromptModule({
                        output: process.stderr,
                    })({
                        type: "input",
                        name: "email",
                        message: "Email address:",
                    });
                    email = answer.email;
                }
                if (email == null || email.trim() === "") {
                    return response_Response.badRequest("Email address is required.");
                }
                if (email.indexOf("@") === -1) {
                    return response_Response.badRequest("Email address is invalid.");
                }
                this.email = email;
                if (password == null || password === "") {
                    if (options.passwordfile) {
                        password = yield NodeUtils.readFirstLine(options.passwordfile);
                    }
                    else if (options.passwordenv && process.env[options.passwordenv]) {
                        password = process.env[options.passwordenv];
                    }
                    else if (this.canInteract) {
                        const answer = yield external_inquirer_namespaceObject.createPromptModule({
                            output: process.stderr,
                        })({
                            type: "password",
                            name: "password",
                            message: "Master password:",
                        });
                        password = answer.password;
                    }
                }
                if (password == null || password === "") {
                    return response_Response.badRequest("Master password is required.");
                }
            }
            let twoFactorToken = options.code;
            let twoFactorMethod = null;
            try {
                if (options.method != null) {
                    const parsed = parseInt(options.method, 10);
                    if (isTwoFactorProviderType(parsed)) {
                        twoFactorMethod = parsed;
                    }
                    else {
                        return response_Response.error("Invalid two-step login method.");
                    }
                }
                // FIXME: Remove when updating file. Eslint update
                // eslint-disable-next-line @typescript-eslint/no-unused-vars
            }
            catch (e) {
                return response_Response.error("Invalid two-step login method.");
            }
            const twoFactor = twoFactorToken == null
                ? null
                : new TokenTwoFactorRequest(twoFactorMethod, twoFactorToken, false);
            try {
                yield this.validatedParams();
                let response = null;
                if (clientId != null && clientSecret != null) {
                    if (!clientId.startsWith("user")) {
                        return response_Response.error("Invalid API Key; Organization API Key currently not supported");
                    }
                    try {
                        response = yield this.loginStrategyService.logIn(new UserApiLoginCredentials(clientId, clientSecret));
                    }
                    catch (e) {
                        // handle API key login failures
                        // Handle invalid client error as server doesn't return a useful message
                        if (((_a = e === null || e === void 0 ? void 0 : e.response) === null || _a === void 0 ? void 0 : _a.error) &&
                            typeof e.response.error === "string" &&
                            e.response.error === "invalid_client") {
                            return response_Response.badRequest("client_id or client_secret is incorrect. Try again.");
                        }
                        // Pass error up to be handled by the outer catch block below
                        throw e;
                    }
                }
                else if (ssoCode != null && ssoCodeVerifier != null) {
                    response = yield this.loginStrategyService.logIn(new SsoLoginCredentials(ssoCode, ssoCodeVerifier, this.ssoRedirectUri, orgIdentifier, undefined, // email to look up 2FA token not required as CLI can't remember 2FA token
                    twoFactor));
                }
                else {
                    response = yield this.loginStrategyService.logIn(new PasswordLoginCredentials(email, password, twoFactor));
                }
                // Begin Acting on initial AuthResult
                if (response.requiresEncryptionKeyMigration) {
                    return response_Response.error(this.i18nService.t("legacyEncryptionUnsupported"));
                }
                // Opting for not checking feature flag since the server will not respond with
                // SsoOrganizationIdentifier if the feature flag is not enabled.
                if (response.requiresSso && this.canInteract) {
                    const ssoPromptData = yield this.makeSsoPromptData();
                    ssoCodeVerifier = ssoPromptData.ssoCodeVerifier;
                    try {
                        const ssoParams = yield this.openSsoPrompt(ssoPromptData.codeChallenge, ssoPromptData.state, response.ssoOrganizationIdentifier);
                        ssoCode = ssoParams.ssoCode;
                        orgIdentifier = ssoParams.orgIdentifier;
                        if (ssoCode != null && ssoCodeVerifier != null) {
                            response = yield this.loginStrategyService.logIn(new SsoLoginCredentials(ssoCode, ssoCodeVerifier, this.ssoRedirectUri, orgIdentifier, undefined, // email to look up 2FA token not required as CLI can't remember 2FA token
                            twoFactor));
                        }
                    }
                    catch (_c) {
                        return response_Response.badRequest("Something went wrong. Try again.");
                    }
                }
                if (response.requiresTwoFactor) {
                    const twoFactorProviders = yield this.twoFactorService.getSupportedProviders(null);
                    if (twoFactorProviders.length === 0) {
                        return response_Response.badRequest("No providers available for this client.");
                    }
                    if (twoFactorMethod != null) {
                        try {
                            selectedProvider = twoFactorProviders.filter((p) => p.type === twoFactorMethod)[0];
                            // FIXME: Remove when updating file. Eslint update
                            // eslint-disable-next-line @typescript-eslint/no-unused-vars
                        }
                        catch (e) {
                            return response_Response.error("Invalid two-step login method.");
                        }
                    }
                    if (selectedProvider == null) {
                        if (twoFactorProviders.length === 1) {
                            selectedProvider = twoFactorProviders[0];
                        }
                        else if (this.canInteract) {
                            const twoFactorOptions = twoFactorProviders.map((p) => p.name);
                            twoFactorOptions.push(new external_inquirer_namespaceObject.Separator());
                            twoFactorOptions.push("Cancel");
                            const answer = yield external_inquirer_namespaceObject.createPromptModule({
                                output: process.stderr,
                            })({
                                type: "list",
                                name: "method",
                                message: "Two-step login method:",
                                choices: twoFactorOptions,
                            });
                            const i = twoFactorOptions.indexOf(answer.method);
                            if (i === twoFactorOptions.length - 1) {
                                return response_Response.error("Login failed.");
                            }
                            selectedProvider = twoFactorProviders[i];
                        }
                        if (selectedProvider == null) {
                            return response_Response.error("Login failed. No provider selected.");
                        }
                    }
                    if (twoFactorToken == null && selectedProvider.type === TwoFactorProviderType.Email) {
                        const emailReq = new TwoFactorEmailRequest();
                        emailReq.email = yield this.loginStrategyService.getEmail();
                        // if the user was logging in with SSO, we need to include the SSO session token
                        if (response.ssoEmail2FaSessionToken != null) {
                            emailReq.ssoEmail2FaSessionToken = response.ssoEmail2FaSessionToken;
                        }
                        emailReq.masterPasswordHash = yield this.loginStrategyService.getMasterPasswordHash();
                        yield this.twoFactorApiService.postTwoFactorEmail(emailReq);
                    }
                    if (twoFactorToken == null) {
                        if (this.canInteract) {
                            const answer = yield external_inquirer_namespaceObject.createPromptModule({
                                output: process.stderr,
                            })({
                                type: "input",
                                name: "token",
                                message: "Two-step login code:",
                            });
                            twoFactorToken = answer.token;
                        }
                        if (twoFactorToken == null || twoFactorToken === "") {
                            return response_Response.badRequest("Code is required.");
                        }
                    }
                    response = yield this.loginStrategyService.logInTwoFactor(new TokenTwoFactorRequest(selectedProvider.type, twoFactorToken));
                }
                // Opting for not checking feature flag since the server will not respond with
                // requiresDeviceVerification if the feature flag is not enabled.
                if (response.requiresDeviceVerification) {
                    let newDeviceToken = null;
                    if (this.canInteract) {
                        const answer = yield external_inquirer_namespaceObject.createPromptModule({
                            output: process.stderr,
                        })({
                            type: "input",
                            name: "token",
                            message: "New device verification required. Enter OTP sent to login email:",
                        });
                        newDeviceToken = answer.token;
                    }
                    if (newDeviceToken == null || newDeviceToken === "") {
                        return response_Response.badRequest("Code is required.");
                    }
                    response = yield this.loginStrategyService.logInNewDeviceVerification(newDeviceToken);
                }
                // We check response two factor again here since MFA could fail based on the logic on ln 226
                if (response.requiresTwoFactor) {
                    return response_Response.error("Login failed.");
                }
                // If we are in the SSO flow and we got a successful login response (we are past rejection scenarios
                // and should always have a userId here), validate that SSO user in MP encryption org has MP set
                // This must be done here b/c we have 2 places we try to login with SSO above and neither has a
                // common handleSsoAuthnResult method to consoldiate this logic into (1. the normal SSO flow and
                // 2. the requiresSso automatic authentication flow)
                if (ssoCode != null && ssoCodeVerifier != null && response.userId) {
                    yield this.validateSsoUserInMpEncryptionOrgHasMp(response.userId);
                }
                // Check if Key Connector domain confirmation is required
                const domainConfirmation = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyConnectorService.requiresDomainConfirmation$(response.userId));
                if (domainConfirmation != null) {
                    const command = new ConfirmKeyConnectorDomainCommand(response.userId, domainConfirmation.keyConnectorUrl, this.keyConnectorService, this.logoutCallback, this.i18nService);
                    const confirmResponse = yield command.run();
                    if (!confirmResponse.success) {
                        return confirmResponse;
                    }
                }
                // Guard against race condition: active account and auth state observables may lag
                // behind state writes. Await them here to let state propagate before fullSync reads them.
                yield firstValueFromOrNull(this.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.filter)((account) => (account === null || account === void 0 ? void 0 : account.id) === response.userId)));
                yield firstValueFromOrNull(this.authService
                    .authStatusFor$(response.userId)
                    .pipe((0,external_rxjs_namespaceObject.filter)((status) => status !== authentication_status_AuthenticationStatus.LoggedOut)));
                // Run full sync before handling success response or password reset flows (to get Master Password Policies)
                yield this.syncService.fullSync(true, { skipTokenRefresh: true });
                // If the user's password is out of compliance, log them out and direct them to the web app.
                if (clientId == null && clientSecret == null) {
                    const forceSetPasswordReason = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.masterPasswordService.forceSetPasswordReason$(response.userId));
                    if (forceSetPasswordReason === ForceSetPasswordReason.AdminForcePasswordReset) {
                        yield this.logoutCallback();
                        return response_Response.error("An organization administrator recently changed your master password. In order to access the vault, you must update your master password now via the web app. You have been logged out.");
                    }
                    else if (forceSetPasswordReason === ForceSetPasswordReason.WeakMasterPassword) {
                        yield this.logoutCallback();
                        return response_Response.error("Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now via the web app. You have been logged out.");
                    }
                }
                yield this.encryptedMigrator.runMigrations(response.userId, password);
                return yield this.handleSuccessResponse(response);
            }
            catch (e) {
                if (e instanceof ErrorResponse &&
                    e.message === "Username or password is incorrect. Try again.") {
                    const env = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.environmentService.environment$);
                    const host = utils_Utils.getHost(env.getWebVaultUrl());
                    return response_Response.error(this.i18nService.t("invalidMasterPasswordConfirmEmailAndHost", host));
                }
                return response_Response.error(e);
            }
        });
    }
    validatedParams() {
        return login_command_awaiter(this, void 0, void 0, function* () {
            const key = yield this.cryptoFunctionService.randomBytes(64);
            process.env.BW_SESSION = utils_Utils.fromBufferToB64(key);
        });
    }
    handleSuccessResponse(response) {
        return login_command_awaiter(this, void 0, void 0, function* () {
            const usesKeyConnector = yield this.keyConnectorService.getUsesKeyConnector(response.userId);
            if ((this.options.sso != null || this.options.apikey != null) &&
                this.canInteract &&
                !usesKeyConnector) {
                const res = new MessageResponse("You are logged in!", "\n" + "To unlock your vault, use the `unlock` command. ex:\n" + "$ bw unlock");
                return response_Response.success(res);
            }
            const res = new MessageResponse("You are logged in!", "\n" +
                "To unlock your vault, set your session key to the `BW_SESSION` environment variable. ex:\n" +
                '$ export BW_SESSION="' +
                process.env.BW_SESSION +
                '"\n' +
                '> $env:BW_SESSION="' +
                process.env.BW_SESSION +
                '"\n\n' +
                "You can also pass the session key to any command with the `--session` option. ex:\n" +
                "$ bw list items --session " +
                process.env.BW_SESSION);
            res.raw = process.env.BW_SESSION;
            return response_Response.success(res);
        });
    }
    apiClientId() {
        return login_command_awaiter(this, void 0, void 0, function* () {
            let clientId = null;
            const storedClientId = process.env.BW_CLIENTID;
            if (storedClientId == null) {
                if (this.canInteract) {
                    const answer = yield external_inquirer_namespaceObject.createPromptModule({
                        output: process.stderr,
                    })({
                        type: "input",
                        name: "clientId",
                        message: "client_id:",
                    });
                    clientId = answer.clientId;
                }
                else {
                    clientId = null;
                }
            }
            else {
                clientId = storedClientId;
            }
            return clientId;
        });
    }
    apiClientSecret() {
        return login_command_awaiter(this, arguments, void 0, function* (isAdditionalAuthentication = false) {
            const additionalAuthenticationMessage = "Additional authentication required.\nAPI key ";
            let clientSecret = null;
            const storedClientSecret = this.clientSecret || process.env.BW_CLIENTSECRET;
            if (storedClientSecret == null) {
                if (this.canInteract) {
                    const answer = yield external_inquirer_namespaceObject.createPromptModule({
                        output: process.stderr,
                    })({
                        type: "input",
                        name: "clientSecret",
                        message: (isAdditionalAuthentication ? additionalAuthenticationMessage : "") + "client_secret:",
                    });
                    clientSecret = answer.clientSecret;
                }
                else {
                    clientSecret = null;
                }
            }
            else {
                clientSecret = storedClientSecret;
            }
            return clientSecret;
        });
    }
    apiIdentifiers() {
        return login_command_awaiter(this, void 0, void 0, function* () {
            return {
                clientId: yield this.apiClientId(),
                clientSecret: yield this.apiClientSecret(),
            };
        });
    }
    /// Generate SSO prompt data: code verifier, code challenge, and state
    makeSsoPromptData() {
        return login_command_awaiter(this, void 0, void 0, function* () {
            const passwordOptions = {
                type: "password",
                length: 64,
                uppercase: true,
                lowercase: true,
                numbers: true,
                special: false,
            };
            const state = yield this.passwordGenerationService.generatePassword(passwordOptions);
            const ssoCodeVerifier = yield this.passwordGenerationService.generatePassword(passwordOptions);
            const codeVerifierHash = yield this.cryptoFunctionService.hash(ssoCodeVerifier, "sha256");
            const codeChallenge = utils_Utils.fromArrayToUrlB64(codeVerifierHash);
            return { ssoCodeVerifier, codeChallenge, state };
        });
    }
    openSsoPrompt(codeChallenge, state, orgSsoIdentifier) {
        return login_command_awaiter(this, void 0, void 0, function* () {
            const env = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.environmentService.environment$);
            return new Promise((resolve, reject) => {
                const callbackServer = external_http_namespaceObject.createServer((req, res) => {
                    const urlString = "http://localhost" + req.url;
                    const url = new URL(urlString);
                    const code = url.searchParams.get("code");
                    const receivedState = url.searchParams.get("state");
                    const orgIdentifier = this.getOrgIdentifierFromState(receivedState);
                    res.setHeader("Content-Type", "text/html");
                    if (code != null && receivedState != null && this.checkState(receivedState, state)) {
                        res.writeHead(200);
                        res.end("<html><head><title>Success | Bitwarden CLI</title></head><body>" +
                            "<h1>Successfully authenticated with the Bitwarden CLI</h1>" +
                            "<p>You may now close this tab and return to the terminal.</p>" +
                            "</body></html>");
                        callbackServer.close(() => resolve({
                            ssoCode: code,
                            orgIdentifier: orgIdentifier,
                        }));
                    }
                    else {
                        res.writeHead(400);
                        res.end("<html><head><title>Failed | Bitwarden CLI</title></head><body>" +
                            "<h1>Something went wrong logging into the Bitwarden CLI</h1>" +
                            "<p>You may now close this tab and return to the terminal.</p>" +
                            "</body></html>");
                        callbackServer.close(() => reject());
                    }
                });
                let foundPort = false;
                const webUrl = env.getWebVaultUrl();
                for (let port = 8065; port <= 8070; port++) {
                    try {
                        this.ssoRedirectUri = "http://localhost:" + port;
                        callbackServer.listen(port, "localhost", () => {
                            const webAppSsoUrl = this.ssoUrlService.buildSsoUrl(webUrl, src_ClientType.Cli, this.ssoRedirectUri, state, codeChallenge, null, orgSsoIdentifier);
                            this.platformUtilsService.launchUri(webAppSsoUrl);
                        });
                        foundPort = true;
                        break;
                    }
                    catch (_a) {
                        // Ignore error since we run the same command up to 5 times.
                    }
                }
                if (!foundPort) {
                    reject();
                }
            });
        });
    }
    getOrgIdentifierFromState(state) {
        if (state === null || state === undefined) {
            return null;
        }
        const stateSplit = state.split("_identifier=");
        return stateSplit.length > 1 ? stateSplit[1] : null;
    }
    checkState(state, checkState) {
        if (state === null || state === undefined) {
            return false;
        }
        if (checkState === null || checkState === undefined) {
            return false;
        }
        const stateSplit = state.split("_identifier=");
        const checkStateSplit = checkState.split("_identifier=");
        return stateSplit[0] === checkStateSplit[0];
    }
    /**
     * Validate that a user logging in with SSO that is in an org using MP encryption
     * has a MP set. If not, they cannot set a MP in the CLI and must use another client.
     * @param userId
     * @returns void
     */
    validateSsoUserInMpEncryptionOrgHasMp(userId) {
        return login_command_awaiter(this, void 0, void 0, function* () {
            const userDecryptionOptions = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.userDecryptionOptionsService.userDecryptionOptionsById$(userId));
            // device trust isn't supported in the CLI as we don't have persistent device key storage.
            const notUsingTrustedDeviceEncryption = !userDecryptionOptions.trustedDeviceOption;
            const notUsingKeyConnector = !userDecryptionOptions.keyConnectorOption;
            if (notUsingTrustedDeviceEncryption &&
                notUsingKeyConnector &&
                !userDecryptionOptions.hasMasterPassword) {
                // If user is in an org that is using MP encryption and they JIT provisioned but
                // have not yet set a MP and come to the CLI to login, they won't be able to unlock
                // or set a MP in the CLI as it isn't supported.
                yield this.logoutCallback();
                throw response_Response.error("In order to log in with SSO from the CLI, you must first log in" +
                    " through the web vault, the desktop, or the extension to set your master password.");
            }
        });
    }
}

;// ./src/auth/commands/logout.command.ts
var logout_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};


class LogoutCommand {
    constructor(authService, i18nService, logoutCallback) {
        this.authService = authService;
        this.i18nService = i18nService;
        this.logoutCallback = logoutCallback;
    }
    run() {
        return logout_command_awaiter(this, void 0, void 0, function* () {
            yield this.logoutCallback();
            this.authService.logOut(() => {
                /* Do nothing */
            });
            const res = new MessageResponse("You have logged out.", null);
            return response_Response.success(res);
        });
    }
}

;// ../../libs/common/src/platform/abstractions/environment.service.ts
/**
 * A subset of available regions, additional regions can be loaded through configuration.
 */
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var Region;
(function (Region) {
    Region["US"] = "US";
    Region["EU"] = "EU";
    Region["SelfHosted"] = "Self-hosted";
})(Region || (Region = {}));
/**
 * The environment service. Provides access to set the current environment urls and region.
 */
class EnvironmentService {
}

;// ./src/key-management/convert-to-key-connector.command.ts
var convert_to_key_connector_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};





class ConvertToKeyConnectorCommand {
    constructor(userId, keyConnectorService, environmentService, organizationApiService, logout, i18nService) {
        this.userId = userId;
        this.keyConnectorService = keyConnectorService;
        this.environmentService = environmentService;
        this.organizationApiService = organizationApiService;
        this.logout = logout;
        this.i18nService = i18nService;
    }
    run() {
        return convert_to_key_connector_command_awaiter(this, void 0, void 0, function* () {
            // If no interaction available, alert user to use web vault
            const canInteract = process.env.BW_NOINTERACTION !== "true";
            if (!canInteract) {
                yield this.logout();
                return response_Response.error(new MessageResponse(this.i18nService.t("organizationUsingKeyConnectorOptInLoggedOut"), null));
            }
            const organization = yield this.keyConnectorService.getManagingOrganization(this.userId);
            const answer = yield external_inquirer_namespaceObject.createPromptModule({ output: process.stderr })({
                type: "list",
                name: "convert",
                message: this.i18nService.t("removeMasterPasswordForOrganizationUserKeyConnector", organization.name, organization.keyConnectorUrl),
                choices: [
                    {
                        name: this.i18nService.t("removeMasterPasswordAndUnlock"),
                        value: "remove",
                    },
                    {
                        name: this.i18nService.t("leaveOrganizationAndUnlock"),
                        value: "leave",
                    },
                    {
                        name: this.i18nService.t("logOut"),
                        value: "exit",
                    },
                ],
            });
            if (answer.convert === "remove") {
                try {
                    yield this.keyConnectorService.migrateUser(organization.keyConnectorUrl, this.userId);
                }
                catch (e) {
                    yield this.logout();
                    throw e;
                }
                // Update environment URL - required for api key login
                const env = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.environmentService.environment$);
                const urls = env.getUrls();
                urls.keyConnector = organization.keyConnectorUrl;
                yield this.environmentService.setEnvironment(Region.SelfHosted, urls);
                return response_Response.success();
            }
            else if (answer.convert === "leave") {
                yield this.organizationApiService.leave(organization.id);
                return response_Response.success();
            }
            else {
                yield this.logout();
                return response_Response.error(this.i18nService.t("youHaveBeenLoggedOut"));
            }
        });
    }
}

;// ./src/key-management/commands/unlock.command.ts
var unlock_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore







class UnlockCommand {
    constructor(accountService, keyService, cryptoFunctionService, logService, keyConnectorService, environmentService, organizationApiService, logout, i18nService, encryptedMigrator, masterPasswordUnlockService, unlockService, configService) {
        this.accountService = accountService;
        this.keyService = keyService;
        this.cryptoFunctionService = cryptoFunctionService;
        this.logService = logService;
        this.keyConnectorService = keyConnectorService;
        this.environmentService = environmentService;
        this.organizationApiService = organizationApiService;
        this.logout = logout;
        this.i18nService = i18nService;
        this.encryptedMigrator = encryptedMigrator;
        this.masterPasswordUnlockService = masterPasswordUnlockService;
        this.unlockService = unlockService;
        this.configService = configService;
    }
    run(password, cmdOptions) {
        return unlock_command_awaiter(this, void 0, void 0, function* () {
            const normalizedOptions = new Options(cmdOptions);
            const passwordResult = yield CliUtils.getPassword(password, normalizedOptions, this.logService);
            if (passwordResult instanceof response_Response) {
                return passwordResult;
            }
            else {
                password = passwordResult;
            }
            yield this.setNewSessionKey();
            const activeAccount = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$);
            if (activeAccount == null) {
                return response_Response.error("No active account found");
            }
            const userId = activeAccount.id;
            try {
                if (yield this.configService.getFeatureFlag(feature_flag_enum_FeatureFlag.UnlockViaSDK)) {
                    yield this.unlockService.unlockWithMasterPassword(userId, password);
                }
                else {
                    const userKey = yield this.masterPasswordUnlockService.unlockWithMasterPassword(password, userId);
                    yield this.keyService.setUserKey(userKey, userId);
                }
            }
            catch (e) {
                return response_Response.error(e.message);
            }
            if (yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyConnectorService.convertAccountRequired$)) {
                const convertToKeyConnectorCommand = new ConvertToKeyConnectorCommand(userId, this.keyConnectorService, this.environmentService, this.organizationApiService, this.logout, this.i18nService);
                const convertResponse = yield convertToKeyConnectorCommand.run();
                if (!convertResponse.success) {
                    return convertResponse;
                }
            }
            yield this.encryptedMigrator.runMigrations(userId, password);
            return this.successResponse();
        });
    }
    setNewSessionKey() {
        return unlock_command_awaiter(this, void 0, void 0, function* () {
            const key = yield this.cryptoFunctionService.randomBytes(64);
            process.env.BW_SESSION = utils_Utils.fromBufferToB64(key);
        });
    }
    successResponse() {
        return unlock_command_awaiter(this, void 0, void 0, function* () {
            const res = new MessageResponse("Your vault is now unlocked!", "\n" +
                "To unlock your vault, set your session key to the `BW_SESSION` environment variable. ex:\n" +
                '$ export BW_SESSION="' +
                process.env.BW_SESSION +
                '"\n' +
                '> $env:BW_SESSION="' +
                process.env.BW_SESSION +
                '"\n\n' +
                "You can also pass the session key to any command with the `--session` option. ex:\n" +
                "$ bw list items --session " +
                process.env.BW_SESSION);
            res.raw = process.env.BW_SESSION;
            return response_Response.success(res);
        });
    }
}
class Options {
    constructor(passedOptions) {
        this.passwordEnv = (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.passwordenv) || (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.passwordEnv);
        this.passwordFile = (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.passwordfile) || (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.passwordFile);
    }
}

;// ./src/base-program.ts
var base_program_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore






const writeLn = CliUtils.writeLn;
class BaseProgram {
    constructor(serviceContainer) {
        this.serviceContainer = serviceContainer;
    }
    processResponse(response, exitImmediately = false) {
        if (!response.success) {
            if (process.env.BW_QUIET !== "true") {
                if (process.env.BW_RESPONSE === "true") {
                    writeLn(this.getJson(response), true, false);
                }
                else {
                    writeLn(external_chalk_namespaceObject.redBright(response.message), true, true);
                }
            }
            const exitCode = process.env.BW_CLEANEXIT ? 0 : 1;
            if (exitImmediately) {
                process.exit(exitCode);
            }
            else {
                process.exitCode = exitCode;
            }
            return;
        }
        if (process.env.BW_RESPONSE === "true") {
            writeLn(this.getJson(response), true, false);
        }
        else if (response.data != null) {
            let out = null;
            if (response.data.object === "template") {
                out = this.getJson(response.data.template);
            }
            if (out == null) {
                if (response.data.object === "string") {
                    const data = response.data.data;
                    if (data != null) {
                        out = data;
                    }
                }
                else if (response.data.object === "list") {
                    out = this.getJson(response.data.data);
                }
                else if (response.data.object === "message") {
                    out = this.getMessage(response);
                }
                else {
                    out = this.getJson(response.data);
                }
            }
            if (out != null && process.env.BW_QUIET !== "true") {
                writeLn(out, true, false);
            }
        }
        if (exitImmediately) {
            process.exit(0);
        }
        else {
            process.exitCode = 0;
        }
    }
    getJson(obj) {
        if (process.env.BW_PRETTY === "true") {
            return JSON.stringify(obj, null, "  ");
        }
        else {
            return JSON.stringify(obj);
        }
    }
    getMessage(response) {
        const message = response.data;
        if (process.env.BW_RAW === "true") {
            return message.raw;
        }
        let out = "";
        if (message.title != null) {
            if (message.noColor) {
                out = message.title;
            }
            else {
                out = external_chalk_namespaceObject.greenBright(message.title);
            }
        }
        if (message.message != null) {
            if (message.title != null) {
                out += "\n";
            }
            out += message.message;
        }
        return out.trim() === "" ? null : out;
    }
    exitIfAuthed() {
        return base_program_awaiter(this, void 0, void 0, function* () {
            const authed = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.serviceContainer.authService.activeAccountStatus$.pipe((0,external_rxjs_namespaceObject.map)((status) => status > authentication_status_AuthenticationStatus.LoggedOut)));
            if (authed) {
                const email = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.serviceContainer.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.map)((a) => a === null || a === void 0 ? void 0 : a.email)));
                this.processResponse(response_Response.error("You are already logged in as " + email + "."), true);
            }
        });
    }
    /**
     * Exist if no user is authenticated
     * @returns the userId of the active account
     */
    exitIfNotAuthed() {
        return base_program_awaiter(this, void 0, void 0, function* () {
            var _a;
            const fail = () => this.processResponse(response_Response.error("You are not logged in."), true);
            const userId = (_a = (yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.serviceContainer.accountService.activeAccount$))) === null || _a === void 0 ? void 0 : _a.id;
            if (!userId) {
                fail();
            }
            const authed = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.serviceContainer.tokenService.hasAccessToken$(userId));
            if (!authed) {
                fail();
            }
            return userId;
        });
    }
    exitIfLocked() {
        return base_program_awaiter(this, void 0, void 0, function* () {
            const userId = yield this.exitIfNotAuthed();
            // If the process.env does not have a BW_SESSION key, then we will never be able to retrieve
            // the auto user key from secure storage. This is because the auto user key is encrypted with
            // the session key.
            const hasUserKey = yield this.serviceContainer.userAutoUnlockKeyService.setUserKeyInMemoryIfAutoUserKeySet(userId);
            if (hasUserKey) {
                // User is unlocked
                return;
            }
            // User is locked
            yield this.handleLockedUser(userId);
        });
    }
    handleLockedUser(userId) {
        return base_program_awaiter(this, void 0, void 0, function* () {
            if (process.env.BW_NOINTERACTION === "true") {
                this.processResponse(response_Response.error("Vault is locked."), true);
                return;
            }
            // must unlock with interaction allowed
            if (yield this.serviceContainer.keyConnectorService.getUsesKeyConnector(userId)) {
                const response = response_Response.error("Your vault is locked. You must unlock your vault using your session key.\n" +
                    "If you do not have your session key, you can get a new one by logging out and logging in again.");
                this.processResponse(response, true);
            }
            else {
                const command = new UnlockCommand(this.serviceContainer.accountService, this.serviceContainer.keyService, this.serviceContainer.cryptoFunctionService, this.serviceContainer.logService, this.serviceContainer.keyConnectorService, this.serviceContainer.environmentService, this.serviceContainer.organizationApiService, this.serviceContainer.logout, this.serviceContainer.i18nService, this.serviceContainer.encryptedMigrator, this.serviceContainer.masterPasswordUnlockService, this.serviceContainer.unlockService, this.serviceContainer.configService);
                const response = yield command.run(null, null);
                if (!response.success) {
                    this.processResponse(response, true);
                }
            }
        });
    }
    exitIfFeatureFlagDisabled(featureFlag) {
        return base_program_awaiter(this, void 0, void 0, function* () {
            const enabled = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.serviceContainer.configService.getFeatureFlag$(featureFlag));
            if (!enabled) {
                this.processResponse(response_Response.error("This command is temporarily unavailable."), true);
            }
        });
    }
}

;// ./src/commands/completion.command.ts
var completion_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore



const validShells = ["zsh"];
class CompletionCommand {
    run(options) {
        return completion_command_awaiter(this, void 0, void 0, function* () {
            const shell = options.shell;
            if (!shell) {
                return response_Response.badRequest("`shell` option was not provided.");
            }
            if (!validShells.includes(shell)) {
                return response_Response.badRequest("Unsupported shell.");
            }
            let content = "";
            if (shell === "zsh") {
                content = this.zshCompletion("bw", external_commander_namespaceObject.program).render();
            }
            const res = new MessageResponse(content, null);
            return response_Response.success(res);
        });
    }
    zshCompletion(rootName, rootCommand) {
        return {
            render: () => {
                return [
                    `#compdef _${rootName} ${rootName}`,
                    "",
                    this.renderCommandBlock(rootName, rootCommand),
                ].join("\n");
            },
        };
    }
    renderCommandBlock(name, command) {
        const { commands = [], options = [] } = command;
        const hasOptions = options.length > 0;
        const hasCommands = commands.length > 0;
        const args = options
            .map(({ long, short, description }) => {
            const aliases = [short, long].filter(Boolean);
            const opts = aliases.join(",");
            const desc = `[${description.replace(`'`, `'"'"'`)}]`;
            return aliases.length > 1
                ? `'(${aliases.join(" ")})'{${opts}}'${desc}'`
                : `'${opts}${desc}'`;
        })
            .concat(`'(-h --help)'{-h,--help}'[output usage information]'`, hasCommands ? '"1: :->cmnds"' : null, '"*::arg:->args"')
            .filter(Boolean);
        const commandBlockFunctionParts = [];
        if (hasCommands) {
            commandBlockFunctionParts.push("local -a commands");
        }
        if (hasOptions) {
            commandBlockFunctionParts.push(`_arguments -C \\\n    ${args.join(` \\\n    `)}`);
        }
        if (hasCommands) {
            commandBlockFunctionParts.push(`case $state in
    cmnds)
      commands=(
        ${commands
                .map((command) => `"${command.name().split(" ")[0]}:${command.description()}"`)
                .join("\n        ")}
      )
      _describe "command" commands
      ;;\n  esac

  case "$words[1]" in
    ${commands
                .map((command) => {
                const commandName = command.name().split(" ")[0];
                return [`${commandName})`, `_${name}_${commandName}`, ";;"].join("\n      ");
            })
                .join("\n    ")}\n  esac`);
        }
        const commandBlocParts = [
            `function _${name} {\n  ${commandBlockFunctionParts.join("\n\n  ")}\n}`,
        ];
        if (hasCommands) {
            commandBlocParts.push(commands.map((c) => this.renderCommandBlock(`${name}_${c.name()}`, c)).join("\n\n"));
        }
        return commandBlocParts.join("\n\n");
    }
}

;// ./src/models/response/string.response.ts
class StringResponse {
    constructor(data) {
        this.object = "string";
        this.data = data;
    }
}

;// ./src/commands/encode.command.ts
var encode_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};



class EncodeCommand {
    run() {
        return encode_command_awaiter(this, void 0, void 0, function* () {
            if (process.stdin.isTTY) {
                return response_Response.badRequest("No stdin was piped in.");
            }
            const input = yield CliUtils.readStdin();
            const b64 = Buffer.from(input, "utf8").toString("base64");
            const res = new StringResponse(b64);
            return response_Response.success(res);
        });
    }
}

;// ./src/models/response/template.response.ts
class TemplateResponse {
    constructor(template) {
        this.object = "template";
        this.template = template;
    }
}

;// ./src/commands/status.command.ts
var status_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};




class StatusCommand {
    constructor(envService, syncService, accountService, authService, userAutoUnlockKeyService) {
        this.envService = envService;
        this.syncService = syncService;
        this.accountService = accountService;
        this.authService = authService;
        this.userAutoUnlockKeyService = userAutoUnlockKeyService;
    }
    run() {
        return status_command_awaiter(this, void 0, void 0, function* () {
            try {
                const baseUrl = yield this.baseUrl();
                const lastSync = yield this.syncService.getLastSync();
                const [userId, email] = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.map)((a) => [a === null || a === void 0 ? void 0 : a.id, a === null || a === void 0 ? void 0 : a.email])));
                const status = yield this.status(userId);
                return response_Response.success(new TemplateResponse({
                    serverUrl: baseUrl,
                    lastSync: lastSync,
                    userEmail: email,
                    userId: userId,
                    status: status,
                }));
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
    baseUrl() {
        return status_command_awaiter(this, void 0, void 0, function* () {
            const env = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.envService.environment$);
            return env.getUrls().base;
        });
    }
    status(userId) {
        return status_command_awaiter(this, void 0, void 0, function* () {
            if (userId != null) {
                yield this.userAutoUnlockKeyService.setUserKeyInMemoryIfAutoUserKeySet(userId);
            }
            const authStatus = yield this.authService.getAuthStatus();
            if (authStatus === authentication_status_AuthenticationStatus.Unlocked) {
                return "unlocked";
            }
            else if (authStatus === authentication_status_AuthenticationStatus.Locked) {
                return "locked";
            }
            else {
                return "unauthenticated";
            }
        });
    }
}

;// ./src/commands/update.command.ts
var update_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};


const CLIENTS_RELEASE_LIST_ENDPOINT = "https://api.github.com/repos/bitwarden/clients/releases";
const DEFAULT_DOWNLOAD_URL = "https://github.com/bitwarden/clients/releases";
const UPDATE_COMMAND = "npm install -g @bitwarden/cli";
class UpdateCommand {
    constructor(platformUtilsService, apiService) {
        this.platformUtilsService = platformUtilsService;
        this.apiService = apiService;
        this.inPkg = false;
        this.inPkg = !!process.pkg;
    }
    run() {
        return update_command_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.nativeFetch(new Request(CLIENTS_RELEASE_LIST_ENDPOINT));
            if (response.status !== 200) {
                return response_Response.error("Error contacting update API: " + response.status);
            }
            const responseJson = yield response.json();
            const cliRelease = responseJson.find((r) => r.tag_name.includes("cli"));
            if (cliRelease === undefined || cliRelease === null) {
                return response_Response.error("Could not find latest CLI version.");
            }
            const currentVersion = yield this.platformUtilsService.getApplicationVersion();
            if (cliRelease.tag_name === "cli-v" + currentVersion) {
                const response = new MessageResponse(null, null);
                response.title = "No update available.";
                response.noColor = true;
                return response_Response.success(response);
            }
            const res = this.getFoundUpdateResponse(cliRelease);
            return response_Response.success(res);
        });
    }
    getFoundUpdateResponse(release) {
        const downloadUrl = this.getDownloadUrl(release.assets);
        const response = new MessageResponse(null, null);
        response.title = "A new version is available: " + release.tag_name;
        response.raw = downloadUrl;
        response.message = this.getMessage(release, downloadUrl);
        return response;
    }
    getMessage(release, downloadUrl) {
        let message = "";
        if (release.body != null && release.body !== "") {
            message = release.body + "\n\n";
        }
        message += "You can download this update at " + downloadUrl;
        if (this.inPkg) {
            message +=
                "\n\nIf you installed this CLI through a package manager " +
                    "you should probably update using its update command instead.";
        }
        else {
            message +=
                "\n\nIf you installed this CLI through NPM " +
                    "you should update using `" +
                    UPDATE_COMMAND +
                    "`";
        }
        return message;
    }
    getDownloadUrl(assets) {
        if (assets == null) {
            return DEFAULT_DOWNLOAD_URL;
        }
        let downloadUrl = DEFAULT_DOWNLOAD_URL;
        for (const a of assets) {
            const download = a.browser_download_url;
            if (download == null) {
                continue;
            }
            if (download.indexOf(".zip") === -1) {
                continue;
            }
            if (process.platform === "win32" && download.indexOf("bw-windows") > -1) {
                downloadUrl = download;
                break;
            }
            else if (process.platform === "darwin" && download.indexOf("bw-macos") > -1) {
                downloadUrl = download;
                break;
            }
            else if (process.platform === "linux" && download.indexOf("bw-linux") > -1) {
                downloadUrl = download;
                break;
            }
        }
        return downloadUrl;
    }
}

;// ./src/platform/commands/config.command.ts
var config_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};





class ConfigCommand {
    constructor(environmentService, accountService) {
        this.environmentService = environmentService;
        this.accountService = accountService;
    }
    run(setting, value, options) {
        return config_command_awaiter(this, void 0, void 0, function* () {
            setting = setting.toLowerCase();
            switch (setting) {
                case "server":
                    return yield this.getOrSetServer(value, options);
                default:
                    return response_Response.badRequest("Unknown setting.");
            }
        });
    }
    getOrSetServer(url, options) {
        return config_command_awaiter(this, void 0, void 0, function* () {
            if ((url == null || url.trim() === "") &&
                !options.webVault &&
                !options.api &&
                !options.identity &&
                !options.icons &&
                !options.notifications &&
                !options.events) {
                const env = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.environmentService.environment$);
                const stringRes = new StringResponse(env.hasBaseUrl() ? env.getUrls().base : "https://bitwarden.com");
                return response_Response.success(stringRes);
            }
            // The server config cannot be updated while a user is actively logged in to the current server
            const activeAccount = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$);
            if (activeAccount) {
                return response_Response.error("Logout required before server config update.");
            }
            url = url === "null" || url === "bitwarden.com" || url === "https://bitwarden.com" ? null : url;
            yield this.environmentService.setEnvironment(Region.SelfHosted, {
                base: url,
                webVault: options.webVault || null,
                api: options.api || null,
                identity: options.identity || null,
                icons: options.icons || null,
                notifications: options.notifications || null,
                events: options.events || null,
                keyConnector: options.keyConnector || null,
            });
            const res = new MessageResponse("Saved setting `config`.", null);
            return response_Response.success(res);
        });
    }
}

;// ../../libs/tools/generator/core/src/data/default-catchall-options.ts
/** The default options for catchall address generation. */
const DefaultCatchallOptions = Object.freeze({
    catchallType: "random",
    catchallDomain: "",
    website: null,
});

;// ../../libs/tools/generator/core/src/data/default-passphrase-boundaries.ts
function initializeBoundaries() {
    const numWords = Object.freeze({
        min: 3,
        max: 20,
    });
    return Object.freeze({
        numWords,
    });
}
/** Immutable default boundaries for passphrase generation.
 * These are used when the policy does not override a value.
 */
const DefaultPassphraseBoundaries = initializeBoundaries();

;// ../../libs/tools/generator/core/src/data/default-password-boundaries.ts
function default_password_boundaries_initializeBoundaries() {
    const length = Object.freeze({
        min: 5,
        max: 128,
    });
    const minDigits = Object.freeze({
        min: 0,
        max: 9,
    });
    const minSpecialCharacters = Object.freeze({
        min: 0,
        max: 9,
    });
    return Object.freeze({
        length,
        minDigits,
        minSpecialCharacters,
    });
}
/** Immutable default boundaries for password generation.
 * These are used when the policy does not override a value.
 */
const DefaultPasswordBoundaries = default_password_boundaries_initializeBoundaries();

;// ../../libs/tools/generator/core/src/data/default-eff-username-options.ts
/** The default options for EFF long word generation. */
const DefaultEffUsernameOptions = Object.freeze({
    wordCapitalize: false,
    wordIncludeNumber: false,
    website: null,
});

;// ../../libs/tools/generator/core/src/data/default-passphrase-generation-options.ts
/** The default options for passphrase generation. */
const DefaultPassphraseGenerationOptions = Object.freeze({
    numWords: 6,
    wordSeparator: "-",
    capitalize: false,
    includeNumber: false,
});

;// ../../libs/tools/generator/core/src/data/default-password-generation-options.ts

/** The default options for password generation. */
const DefaultPasswordGenerationOptions = Object.freeze({
    length: 14,
    minLength: DefaultPasswordBoundaries.length.min,
    ambiguous: true,
    uppercase: true,
    minUppercase: 1,
    lowercase: true,
    minLowercase: 1,
    number: true,
    minNumber: 1,
    special: false,
    minSpecial: 0,
});

;// ../../libs/tools/generator/core/src/data/default-subaddress-generator-options.ts
/** The default options for email subaddress generation. */
const DefaultSubaddressOptions = Object.freeze({
    subaddressType: "random",
    subaddressEmail: "",
    website: null,
});

;// ../../libs/common/src/tools/extension/vendor/data.ts
const data_Vendor = Object.freeze({
    addyio: "addyio",
    bitwarden: "bitwarden", // RESERVED
    duckduckgo: "duckduckgo",
    fastmail: "fastmail",
    forwardemail: "forwardemail",
    mozilla: "mozilla",
    simplelogin: "simplelogin",
});

;// ../../libs/common/src/tools/private-classifier.ts
class PrivateClassifier {
    constructor(keys = undefined) {
        this.keys = keys;
    }
    classify(value) {
        var _a;
        const pickMe = JSON.parse(JSON.stringify(value));
        const keys = (_a = this.keys) !== null && _a !== void 0 ? _a : Object.keys(pickMe);
        const picked = {};
        for (const key of keys) {
            picked[key] = pickMe[key];
        }
        const secret = picked;
        return { disclosed: null, secret };
    }
    declassify(_disclosed, secret) {
        var _a;
        const result = {};
        const keys = (_a = this.keys) !== null && _a !== void 0 ? _a : Object.keys(secret);
        for (const key of keys) {
            result[key] = secret[key];
        }
        return result;
    }
}

;// ../../libs/common/src/tools/public-classifier.ts
class PublicClassifier {
    constructor(keys) {
        this.keys = keys;
    }
    classify(value) {
        const pickMe = JSON.parse(JSON.stringify(value));
        const picked = {};
        for (const key of this.keys) {
            picked[key] = pickMe[key];
        }
        const disclosed = picked;
        return { disclosed, secret: null };
    }
    declassify(disclosed, _secret) {
        const result = {};
        for (const key of this.keys) {
            result[key] = disclosed[key];
        }
        return result;
    }
}

;// ../../libs/common/src/tools/state/buffered-key-definition.ts

/** Storage and mapping settings for data stored by a `BufferedState`.
 */
class BufferedKeyDefinition {
    /**
     * Defines a buffered state
     * @param stateDefinition The domain of the buffer
     * @param key Domain key that identifies the buffered value. This key must
     *    not be reused in any capacity.
     * @param options Configures the operation of the buffered state.
     */
    constructor(stateDefinition, key, options) {
        this.stateDefinition = stateDefinition;
        this.key = key;
        this.options = options;
    }
    /** Converts the buffered key definition to a state provider
     *  key definition
     */
    toKeyDefinition() {
        const bufferedKey = new UserKeyDefinition(this.stateDefinition, this.key, this.options);
        return bufferedKey;
    }
    /** Checks whether the dependency triggers an overwrite. */
    shouldOverwrite(dependency) {
        var _a;
        const shouldOverwrite = (_a = this.options) === null || _a === void 0 ? void 0 : _a.shouldOverwrite;
        if (shouldOverwrite) {
            return shouldOverwrite(dependency);
        }
        return dependency ? true : false;
    }
    /** Converts the input data format to its output format.
     *  @returns the converted value.
     */
    map(input, dependency) {
        var _a;
        const map = (_a = this.options) === null || _a === void 0 ? void 0 : _a.map;
        if (map) {
            return map(input, dependency);
        }
        return Promise.resolve(input);
    }
    /** Checks whether the input type can be converted to the output type.
     *  @returns `true` if the definition is defined and valid, otherwise `false`.
     */
    isValid(input, dependency) {
        var _a;
        if (input === null) {
            return Promise.resolve(false);
        }
        const isValid = (_a = this.options) === null || _a === void 0 ? void 0 : _a.isValid;
        if (isValid) {
            return isValid(input, dependency);
        }
        return Promise.resolve(input ? true : false);
    }
}

;// ../../libs/tools/generator/core/src/integration/addy-io.ts





// default values
const defaultSettings = Object.freeze({
    token: "",
    domain: "",
    baseUrl: "",
});
// supported RPC calls
const createForwardingEmail = Object.freeze({
    url(_request, context) {
        return context.baseUrl() + "/api/v1/aliases";
    },
    body(request, context) {
        return {
            domain: context.emailDomain(),
            description: context.generatedBy(request, { extractHostname: true, maxLength: 200 }),
        };
    },
    hasJsonPayload(response) {
        return response.status === 200 || response.status === 201;
    },
    processJson(json) {
        var _a;
        return [(_a = json === null || json === void 0 ? void 0 : json.data) === null || _a === void 0 ? void 0 : _a.email];
    },
});
// forwarder configuration
const forwarder = Object.freeze({
    defaultSettings,
    createForwardingEmail,
    request: ["token", "baseUrl", "domain"],
    settingsConstraints: {
        token: { required: true },
        domain: { required: true },
        baseUrl: {},
    },
    local: {
        settings: {
            // FIXME: integration should issue keys at runtime
            // based on integrationId & extension metadata
            // e.g. key: "forwarder.AddyIo.local.settings",
            key: "addyIoForwarder",
            target: "object",
            format: "secret-state",
            frame: 512,
            classifier: new PrivateClassifier(),
            state: GENERATOR_DISK,
            initial: defaultSettings,
            options: {
                deserializer: (value) => value,
                clearOn: ["logout"],
            },
        },
        import: {
            key: "forwarder.AddyIo.local.import",
            target: "object",
            format: "plain",
            classifier: new PublicClassifier(["token", "baseUrl", "domain"]),
            state: GENERATOR_MEMORY,
            options: {
                deserializer: (value) => value,
                clearOn: ["logout", "lock"],
            },
        },
    },
    settings: new UserKeyDefinition(GENERATOR_DISK, "addyIoForwarder", {
        deserializer: (value) => value,
        clearOn: [],
    }),
    importBuffer: new BufferedKeyDefinition(GENERATOR_DISK, "addyIoBuffer", {
        deserializer: (value) => value,
        clearOn: ["logout"],
    }),
});
const AddyIo = Object.freeze({
    // integration
    id: data_Vendor.addyio,
    name: "Addy.io",
    extends: ["forwarder"],
    // hosting
    selfHost: "maybe",
    baseUrl: "https://app.addy.io",
    authenticate(_request, context) {
        return { Authorization: "Bearer " + context.authenticationToken() };
    },
    // extensions
    forwarder,
});

;// ../../libs/tools/generator/core/src/integration/duck-duck-go.ts





// default values
const duck_duck_go_defaultSettings = Object.freeze({
    token: "",
});
// supported RPC calls
const duck_duck_go_createForwardingEmail = Object.freeze({
    url(_request, context) {
        return context.baseUrl() + "/email/addresses";
    },
    body(_request, _context) {
        return undefined;
    },
    hasJsonPayload(response) {
        return response.status === 200 || response.status === 201;
    },
    processJson(json) {
        return [`${json.address}@duck.com`];
    },
});
// forwarder configuration
const duck_duck_go_forwarder = Object.freeze({
    defaultSettings: duck_duck_go_defaultSettings,
    createForwardingEmail: duck_duck_go_createForwardingEmail,
    request: ["token"],
    settingsConstraints: {
        token: { required: true },
    },
    local: {
        settings: {
            // FIXME: integration should issue keys at runtime
            // based on integrationId & extension metadata
            // e.g. key: "forwarder.DuckDuckGo.local.settings",
            key: "duckDuckGoForwarder",
            target: "object",
            format: "secret-state",
            frame: 512,
            classifier: new PrivateClassifier(),
            state: GENERATOR_DISK,
            initial: duck_duck_go_defaultSettings,
            options: {
                deserializer: (value) => value,
                clearOn: ["logout"],
            },
        },
        import: {
            key: "forwarder.DuckDuckGo.local.import",
            target: "object",
            format: "plain",
            classifier: new PublicClassifier(["token"]),
            state: GENERATOR_MEMORY,
            options: {
                deserializer: (value) => value,
                clearOn: ["logout", "lock"],
            },
        },
    },
    settings: new UserKeyDefinition(GENERATOR_DISK, "duckDuckGoForwarder", {
        deserializer: (value) => value,
        clearOn: [],
    }),
    importBuffer: new BufferedKeyDefinition(GENERATOR_DISK, "duckDuckGoBuffer", {
        deserializer: (value) => value,
        clearOn: ["logout"],
    }),
});
// integration-wide configuration
const DuckDuckGo = Object.freeze({
    id: data_Vendor.duckduckgo,
    name: "DuckDuckGo",
    baseUrl: "https://quack.duckduckgo.com/api",
    selfHost: "never",
    extends: ["forwarder"],
    authenticate(_request, context) {
        return { Authorization: "Bearer " + context.authenticationToken() };
    },
    forwarder: duck_duck_go_forwarder,
});

;// ../../libs/tools/generator/core/src/integration/fastmail.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore





// default values
const fastmail_defaultSettings = Object.freeze({
    domain: "",
    prefix: "",
    token: "",
});
// supported RPC calls
const getAccountId = Object.freeze({
    url(_request, context) {
        // cannot use "/.well-known/jmap" because integration RPCs
        // never follow redirects
        return context.baseUrl() + "/jmap/session";
    },
    hasJsonPayload(response) {
        return response.status === 200;
    },
    processJson(json, context) {
        var _a, _b;
        const result = (_b = (_a = json.primaryAccounts) === null || _a === void 0 ? void 0 : _a["https://www.fastmail.com/dev/maskedemail"]) !== null && _b !== void 0 ? _b : undefined;
        return [result, result ? undefined : context.missingAccountIdCause()];
    },
});
const fastmail_createForwardingEmail = Object.freeze({
    url(_request, context) {
        return context.baseUrl() + "/jmap/api/";
    },
    body(request, context) {
        const body = {
            using: ["https://www.fastmail.com/dev/maskedemail", "urn:ietf:params:jmap:core"],
            methodCalls: [
                [
                    "MaskedEmail/set",
                    {
                        accountId: request.accountId,
                        create: {
                            "new-masked-email": {
                                state: "enabled",
                                description: "",
                                forDomain: context.website(request),
                                emailPrefix: "",
                            },
                        },
                    },
                    "0",
                ],
            ],
        };
        return body;
    },
    hasJsonPayload(response) {
        return response.status === 200;
    },
    processJson(json) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
        if (json.methodResponses != null &&
            json.methodResponses.length > 0 &&
            json.methodResponses[0].length > 0) {
            if (json.methodResponses[0][0] === "MaskedEmail/set") {
                if (((_b = (_a = json.methodResponses[0][1]) === null || _a === void 0 ? void 0 : _a.created) === null || _b === void 0 ? void 0 : _b["new-masked-email"]) != null) {
                    const email = (_e = (_d = (_c = json.methodResponses[0][1]) === null || _c === void 0 ? void 0 : _c.created) === null || _d === void 0 ? void 0 : _d["new-masked-email"]) === null || _e === void 0 ? void 0 : _e.email;
                    return [email];
                }
                if (((_g = (_f = json.methodResponses[0][1]) === null || _f === void 0 ? void 0 : _f.notCreated) === null || _g === void 0 ? void 0 : _g["new-masked-email"]) != null) {
                    const errorDescription = (_k = (_j = (_h = json.methodResponses[0][1]) === null || _h === void 0 ? void 0 : _h.notCreated) === null || _j === void 0 ? void 0 : _j["new-masked-email"]) === null || _k === void 0 ? void 0 : _k.description;
                    return [undefined, errorDescription];
                }
            }
            else if (json.methodResponses[0][0] === "error") {
                const errorDescription = (_l = json.methodResponses[0][1]) === null || _l === void 0 ? void 0 : _l.description;
                return [undefined, errorDescription];
            }
        }
    },
});
// forwarder configuration
const fastmail_forwarder = Object.freeze({
    defaultSettings: fastmail_defaultSettings,
    createForwardingEmail: fastmail_createForwardingEmail,
    getAccountId,
    request: ["token"],
    settingsConstraints: {
        token: { required: true },
        domain: { required: true },
        prefix: {},
    },
    local: {
        settings: {
            // FIXME: integration should issue keys at runtime
            // based on integrationId & extension metadata
            // e.g. key: "forwarder.Fastmail.local.settings"
            key: "fastmailForwarder",
            target: "object",
            format: "secret-state",
            frame: 512,
            classifier: new PrivateClassifier(),
            state: GENERATOR_DISK,
            initial: fastmail_defaultSettings,
            options: {
                deserializer: (value) => value,
                clearOn: ["logout"],
            },
        },
        import: {
            key: "forwarder.Fastmail.local.import",
            target: "object",
            format: "plain",
            classifier: new PublicClassifier(["token"]),
            state: GENERATOR_MEMORY,
            options: {
                deserializer: (value) => value,
                clearOn: ["logout", "lock"],
            },
        },
    },
    settings: new UserKeyDefinition(GENERATOR_DISK, "fastmailForwarder", {
        deserializer: (value) => value,
        clearOn: [],
    }),
    importBuffer: new BufferedKeyDefinition(GENERATOR_DISK, "fastmailBuffer", {
        deserializer: (value) => value,
        clearOn: ["logout"],
    }),
});
// integration-wide configuration
const Fastmail = Object.freeze({
    id: data_Vendor.fastmail,
    name: "Fastmail",
    baseUrl: "https://api.fastmail.com",
    selfHost: "maybe",
    extends: ["forwarder"],
    authenticate(_request, context) {
        return { Authorization: "Bearer " + context.authenticationToken() };
    },
    forwarder: fastmail_forwarder,
});

;// ../../libs/tools/generator/core/src/integration/firefox-relay.ts





// default values
const firefox_relay_defaultSettings = Object.freeze({
    token: "",
});
// supported RPC calls
const firefox_relay_createForwardingEmail = Object.freeze({
    url(_request, context) {
        return context.baseUrl() + "/v1/relayaddresses/";
    },
    body(request, context) {
        return {
            enabled: true,
            generated_for: context.website(request, { maxLength: 255 }),
            description: context.generatedBy(request, { extractHostname: true, maxLength: 64 }),
        };
    },
    hasJsonPayload(response) {
        return response.status === 200 || response.status === 201;
    },
    processJson(json) {
        return [json.full_address];
    },
});
// forwarder configuration
const firefox_relay_forwarder = Object.freeze({
    defaultSettings: firefox_relay_defaultSettings,
    createForwardingEmail: firefox_relay_createForwardingEmail,
    request: ["token"],
    settingsConstraints: {
        token: { required: true },
    },
    local: {
        settings: {
            // FIXME: integration should issue keys at runtime
            // based on integrationId & extension metadata
            // e.g. key: "forwarder.Firefox.local.settings",
            key: "firefoxRelayForwarder",
            target: "object",
            format: "secret-state",
            frame: 512,
            classifier: new PrivateClassifier(),
            state: GENERATOR_DISK,
            initial: firefox_relay_defaultSettings,
            options: {
                deserializer: (value) => value,
                clearOn: ["logout"],
            },
        },
        import: {
            key: "forwarder.Firefox.local.import",
            target: "object",
            format: "plain",
            classifier: new PublicClassifier(["token"]),
            state: GENERATOR_MEMORY,
            options: {
                deserializer: (value) => value,
                clearOn: ["logout", "lock"],
            },
        },
    },
    settings: new UserKeyDefinition(GENERATOR_DISK, "firefoxRelayForwarder", {
        deserializer: (value) => value,
        clearOn: [],
    }),
    importBuffer: new BufferedKeyDefinition(GENERATOR_DISK, "firefoxRelayBuffer", {
        deserializer: (value) => value,
        clearOn: ["logout"],
    }),
});
// integration-wide configuration
const FirefoxRelay = Object.freeze({
    id: data_Vendor.mozilla,
    name: "Firefox Relay",
    baseUrl: "https://relay.firefox.com/api",
    selfHost: "never",
    extends: ["forwarder"],
    authenticate(_request, context) {
        return { Authorization: "Token " + context.authenticationToken() };
    },
    forwarder: firefox_relay_forwarder,
});

;// ../../libs/tools/generator/core/src/integration/forward-email.ts





// default values
const forward_email_defaultSettings = Object.freeze({
    token: "",
    domain: "",
});
// supported RPC calls
const forward_email_createForwardingEmail = Object.freeze({
    url(_request, context) {
        const domain = context.emailDomain();
        return context.baseUrl() + `/v1/domains/${domain}/aliases`;
    },
    body(request, context) {
        return {
            labels: context.website(request),
            description: context.generatedBy(request),
        };
    },
    hasJsonPayload(response) {
        return response.status === 200 || response.status === 201;
    },
    processJson(json, context) {
        var _a;
        const { name, domain } = json;
        const domainPart = (_a = domain === null || domain === void 0 ? void 0 : domain.name) !== null && _a !== void 0 ? _a : context.emailDomain();
        return [`${name}@${domainPart}`];
    },
});
// forwarder configuration
const forward_email_forwarder = Object.freeze({
    defaultSettings: forward_email_defaultSettings,
    request: ["token", "domain"],
    settingsConstraints: {
        token: { required: true },
        domain: { required: true },
    },
    local: {
        settings: {
            // FIXME: integration should issue keys at runtime
            // based on integrationId & extension metadata
            // e.g. key: "forwarder.ForwardEmail.local.settings",
            key: "forwardEmailForwarder",
            target: "object",
            format: "secret-state",
            frame: 512,
            classifier: new PrivateClassifier(),
            state: GENERATOR_DISK,
            initial: forward_email_defaultSettings,
            options: {
                deserializer: (value) => value,
                clearOn: ["logout"],
            },
        },
        import: {
            key: "forwarder.ForwardEmail.local.import",
            target: "object",
            format: "plain",
            classifier: new PublicClassifier(["token", "domain"]),
            state: GENERATOR_MEMORY,
            options: {
                deserializer: (value) => value,
                clearOn: ["logout", "lock"],
            },
        },
    },
    settings: new UserKeyDefinition(GENERATOR_DISK, "forwardEmailForwarder", {
        deserializer: (value) => value,
        clearOn: [],
    }),
    importBuffer: new BufferedKeyDefinition(GENERATOR_DISK, "forwardEmailBuffer", {
        deserializer: (value) => value,
        clearOn: ["logout"],
    }),
    createForwardingEmail: forward_email_createForwardingEmail,
});
const ForwardEmail = Object.freeze({
    // integration metadata
    id: data_Vendor.forwardemail,
    name: "Forward Email",
    extends: ["forwarder"],
    // service provider
    selfHost: "never",
    baseUrl: "https://api.forwardemail.net",
    authenticate(_request, context) {
        return { Authorization: "Basic " + context.authenticationToken({ base64: true, suffix: ":" }) };
    },
    // specialized configurations
    forwarder: forward_email_forwarder,
});

;// ../../libs/tools/generator/core/src/integration/simple-login.ts





// default values
const simple_login_defaultSettings = Object.freeze({
    token: "",
    domain: "",
    baseUrl: "",
});
// supported RPC calls
const simple_login_createForwardingEmail = Object.freeze({
    url(request, context) {
        const endpoint = context.baseUrl() + "/api/alias/random/new";
        const hostname = context.website(request);
        const url = hostname !== "" ? `${endpoint}?hostname=${hostname}` : endpoint;
        return url;
    },
    body(request, context) {
        return { note: context.generatedBy(request) };
    },
    hasJsonPayload(response) {
        return response.status === 200 || response.status === 201;
    },
    processJson(json) {
        return [json === null || json === void 0 ? void 0 : json.alias];
    },
});
// forwarder configuration
const simple_login_forwarder = Object.freeze({
    defaultSettings: simple_login_defaultSettings,
    createForwardingEmail: simple_login_createForwardingEmail,
    request: ["token", "baseUrl"],
    settingsConstraints: {
        token: { required: true },
    },
    local: {
        settings: {
            // FIXME: integration should issue keys at runtime
            // based on integrationId & extension metadata
            // e.g. key: "forwarder.SimpleLogin.local.settings",
            key: "simpleLoginForwarder",
            target: "object",
            format: "secret-state",
            frame: 512,
            classifier: new PrivateClassifier(),
            state: GENERATOR_DISK,
            initial: simple_login_defaultSettings,
            options: {
                deserializer: (value) => value,
                clearOn: ["logout"],
            },
        },
        import: {
            key: "forwarder.SimpleLogin.local.import",
            target: "object",
            format: "plain",
            classifier: new PublicClassifier(["token", "baseUrl"]),
            state: GENERATOR_MEMORY,
            options: {
                deserializer: (value) => value,
                clearOn: ["logout", "lock"],
            },
        },
    },
    settings: new UserKeyDefinition(GENERATOR_DISK, "simpleLoginForwarder", {
        deserializer: (value) => value,
        clearOn: [],
    }),
    importBuffer: new BufferedKeyDefinition(GENERATOR_DISK, "simpleLoginBuffer", {
        deserializer: (value) => value,
        clearOn: ["logout"],
    }),
});
// integration-wide configuration
const SimpleLogin = Object.freeze({
    id: data_Vendor.simplelogin,
    name: "SimpleLogin",
    selfHost: "maybe",
    extends: ["forwarder"],
    baseUrl: "https://app.simplelogin.io",
    authenticate(_request, context) {
        return { Authentication: context.authenticationToken() };
    },
    forwarder: simple_login_forwarder,
});

;// ../../libs/tools/generator/core/src/data/integrations.ts






/** Fixed list of integrations available to the application
 *  @example
 *
 *  // Use `toCredentialGeneratorConfiguration(id :ForwarderIntegration)`
 *  // to convert an integration to a generator configuration
 *  const generator = toCredentialGeneratorConfiguration(Integrations.AddyIo);
 */
const integrations_Integrations = Object.freeze({
    AddyIo: AddyIo,
    DuckDuckGo: DuckDuckGo,
    Fastmail: Fastmail,
    FirefoxRelay: FirefoxRelay,
    ForwardEmail: ForwardEmail,
    SimpleLogin: SimpleLogin,
});
const integrations = new Map(Object.values(integrations_Integrations).map((i) => [i.id, i]));
function integrations_getForwarderConfiguration(id) {
    // these casts are for compatibility; `IntegrationId` is the old form of `VendorId`
    const maybeForwarder = integrations.get(id);
    if (maybeForwarder && "forwarder" in maybeForwarder) {
        return maybeForwarder;
    }
    else {
        return null;
    }
}

;// ../../libs/tools/generator/core/src/data/index.ts









;// ../../libs/common/src/tools/integration/rpc/rest-client.ts
var rest_client_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
/** Makes remote procedure calls using a RESTful interface. */
class rest_client_RestClient {
    constructor(api, i18n) {
        this.api = api;
        this.i18n = i18n;
    }
    /** uses the fetch API to request a JSON payload. */
    // FIXME: once legacy password generator is removed, replace forwarder-specific error
    //   messages with RPC-generalized ones.
    fetchJson(rpc, params) {
        return rest_client_awaiter(this, void 0, void 0, function* () {
            // run the request
            const request = rpc.toRequest(params);
            const response = yield this.api.nativeFetch(request);
            let result = undefined;
            let errorKey = undefined;
            let errorMessage = undefined;
            const commonError = yield this.detectCommonErrors(response);
            if (commonError) {
                [errorKey, errorMessage] = commonError;
            }
            else if (rpc.hasJsonPayload(response)) {
                [result, errorMessage] = rpc.processJson(yield response.json());
            }
            if (result) {
                return result;
            }
            // handle failures
            errorKey !== null && errorKey !== void 0 ? errorKey : (errorKey = errorMessage ? "forwarderError" : "forwarderUnknownError");
            const error = this.i18n.t(errorKey, rpc.requestor.name, errorMessage);
            throw error;
        });
    }
    detectCommonErrors(response) {
        return rest_client_awaiter(this, void 0, void 0, function* () {
            if (response.status === 401) {
                const message = yield this.tryGetErrorMessage(response);
                const key = message ? "forwaderInvalidTokenWithMessage" : "forwaderInvalidToken";
                return [key, message];
            }
            else if (response.status === 403) {
                const message = yield this.tryGetErrorMessage(response);
                const key = message ? "forwaderInvalidOperationWithMessage" : "forwaderInvalidOperation";
                return [key, message];
            }
            else if (response.status >= 400) {
                const message = yield this.tryGetErrorMessage(response);
                const key = message ? "forwarderError" : "forwarderUnknownError";
                return [key, message];
            }
        });
    }
    tryGetErrorMessage(response) {
        return rest_client_awaiter(this, void 0, void 0, function* () {
            var _a, _b, _c;
            const body = (_a = (yield response.text())) !== null && _a !== void 0 ? _a : "";
            // nullish continues processing; false returns undefined
            // FIXME: inspect content-type header to determine extraction process
            const error = (_c = (_b = this.tryFindErrorAsJson(body)) !== null && _b !== void 0 ? _b : this.tryFindErrorAsText(body)) !== null && _c !== void 0 ? _c : response.statusText;
            return error || undefined;
        });
    }
    tryFindErrorAsJson(body) {
        var _a, _b, _c, _d, _e;
        // tryParse JSON object or string
        const parsable = body.startsWith("{") || body.startsWith(`'`) || body.startsWith(`"`);
        if (!parsable) {
            // fail-and-continue because it's not JSON
            return undefined;
        }
        let parsed = undefined;
        try {
            parsed = JSON.parse(body);
        }
        catch (_f) {
            // fail-and-exit in case `body` is malformed JSON
            return false;
        }
        // could be a string
        if (parsed && typeof parsed === "string") {
            return parsed;
        }
        // could be { error?: T, message?: U }
        const error = (_b = (_a = parsed.error) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : null;
        const message = (_d = (_c = parsed.message) === null || _c === void 0 ? void 0 : _c.toString()) !== null && _d !== void 0 ? _d : null;
        // `false` signals no message found
        const result = error && message ? `${error}: ${message}` : ((_e = error !== null && error !== void 0 ? error : message) !== null && _e !== void 0 ? _e : false);
        return result;
    }
    tryFindErrorAsText(body) {
        if (!body.length || body.includes("<")) {
            return undefined;
        }
        return body;
    }
}

;// ../../libs/common/src/tools/integration/rpc/index.ts







// EXTERNAL MODULE: ../../node_modules/@bitwarden/commercial-sdk-internal/bitwarden_wasm_internal_bg.js
var bitwarden_wasm_internal_bg = __webpack_require__(431);
;// ../../libs/common/src/platform/abstractions/sdk/sdk-load.service.ts
var sdk_load_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

class SdkLoadFailedError extends Error {
    constructor(error) {
        super(`SDK loading failed: ${error}`);
    }
}
class SdkLoadService {
    /**
     * Load WASM and initalize SDK-JS integrations such as logging.
     * This method should be called once at the start of the application.
     * Raw functions and classes from the SDK can be used after this method resolves.
     */
    loadAndInit() {
        return sdk_load_service_awaiter(this, void 0, void 0, function* () {
            try {
                yield this.load();
                (0,bitwarden_wasm_internal_bg/* init_sdk */.Geh)(SdkLoadService.logLevel);
                SdkLoadService.markAsReady();
            }
            catch (error) {
                SdkLoadService.markAsFailed(error);
            }
        });
    }
}
SdkLoadService.logLevel = bitwarden_wasm_internal_bg/* LogLevel */.$bb.Info;
/**
 * This promise is resolved when the SDK is ready to be used. Use it when your code might run early and/or is not able to use DI.
 * Beware that WASM always requires a load step which makes it tricky to use functions and classes directly, it is therefore recommended
 * to use the SDK through the {@link SdkService}. Only use this promise in advanced scenarios!
 *
 * @example
 * ```typescript
 * import { pureFunction } from "@bitwarden/sdk-internal";
 *
 * async function myFunction() {
 *   await SdkLoadService.Ready;
 *   pureFunction();
 * }
 * ```
 */
SdkLoadService.Ready = new Promise((resolve, reject) => {
    SdkLoadService.markAsReady = resolve;
    SdkLoadService.markAsFailed = (error) => reject(new SdkLoadFailedError(error));
});

;// ../../libs/tools/generator/core/src/engine/purecrypto-randomizer.ts
var purecrypto_randomizer_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};


/**
 * A randomizer backed by the SDK.
 * Note: This should be replaced by higher level functions in the SDK eventually.
 **/
class purecrypto_randomizer_PureCryptoRandomizer {
    /**
     * instantiates the type.
     */
    constructor() { }
    pick(list) {
        return purecrypto_randomizer_awaiter(this, void 0, void 0, function* () {
            var _a;
            const length = (_a = list === null || list === void 0 ? void 0 : list.length) !== null && _a !== void 0 ? _a : 0;
            if (length <= 0) {
                throw new Error("list must have at least one entry.");
            }
            const index = yield this.uniform(0, list.length - 1);
            return list[index];
        });
    }
    pickWord(list, options) {
        return purecrypto_randomizer_awaiter(this, void 0, void 0, function* () {
            var _a, _b;
            let word = yield this.pick(list);
            if ((_a = options === null || options === void 0 ? void 0 : options.titleCase) !== null && _a !== void 0 ? _a : false) {
                word = word.charAt(0).toUpperCase() + word.slice(1);
            }
            if ((_b = options === null || options === void 0 ? void 0 : options.number) !== null && _b !== void 0 ? _b : false) {
                yield SdkLoadService.Ready;
                const num = bitwarden_wasm_internal_bg/* PureCrypto */.IEs.random_number(0, 9);
                word = word + num.toString();
            }
            return word;
        });
    }
    // ref: https://stackoverflow.com/a/12646864/1090359
    shuffle(items, options) {
        return purecrypto_randomizer_awaiter(this, void 0, void 0, function* () {
            var _a, _b;
            const length = (_a = items === null || items === void 0 ? void 0 : items.length) !== null && _a !== void 0 ? _a : 0;
            if (length <= 0) {
                throw new Error("items must have at least one entry.");
            }
            const shuffled = ((_b = options === null || options === void 0 ? void 0 : options.copy) !== null && _b !== void 0 ? _b : true) ? [...items] : items;
            for (let i = shuffled.length - 1; i > 0; i--) {
                const j = yield this.uniform(0, i);
                [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
            }
            return shuffled;
        });
    }
    chars(length) {
        return purecrypto_randomizer_awaiter(this, void 0, void 0, function* () {
            let str = "";
            const charSet = "abcdefghijklmnopqrstuvwxyz1234567890";
            for (let i = 0; i < length; i++) {
                const randomCharIndex = yield this.uniform(0, charSet.length - 1);
                str += charSet.charAt(randomCharIndex);
            }
            return str;
        });
    }
    uniform(min, max) {
        return purecrypto_randomizer_awaiter(this, void 0, void 0, function* () {
            yield SdkLoadService.Ready;
            return bitwarden_wasm_internal_bg/* PureCrypto */.IEs.random_number(min, max);
        });
    }
}

;// ../../libs/common/src/tools/util.ts
/** Recursively freeze an object's own keys
 *  @param value the value to freeze
 *  @returns `value`
 *  @remarks this function is derived from MDN's `deepFreeze`, which
 *   has been committed to the public domain.
 */
function deepFreeze(value) {
    const keys = Reflect.ownKeys(value);
    for (const key of keys) {
        const own = value[key];
        if (own && typeof own === "object") {
            deepFreeze(own);
        }
    }
    return Object.freeze(value);
}
/** Type guard that returns `true` when the value is an i18n key.  */
function isI18nKey(value) {
    return typeof value === "string";
}
/** Type guard that returns `true` when the value requires no translation.
 *  @remarks the literal value can be accessed using the `.literal` property.
 */
function isLiteral(value) {
    return typeof value === "object" && "literal" in value;
}

;// ../../libs/tools/generator/core/src/metadata/data.ts

/** algorithms for generating credentials */
const Algorithm = Object.freeze({
    /** A password composed of random characters */
    password: "password",
    /** A password composed of random words from the EFF word list */
    passphrase: "passphrase",
    /** A username composed of words from the EFF word list */
    username: "username",
    /** An email username composed of random characters */
    catchall: "catchall",
    /** An email username composed of words from the EFF word list  */
    plusAddress: "subaddress",
});
/** categorizes credentials according to their use-case outside of Bitwarden */
const data_Type = Object.freeze({
    password: "password",
    username: "username",
    email: "email",
});
/** categorizes settings according to their expected use-case within Bitwarden */
const data_Profile = Object.freeze({
    /** account-level generator options. This is the default.
     *  @remarks these are the options displayed on the generator tab
     */
    account: "account",
    // FIXME: consider adding a profile for bitwarden's master password
});
/** Credential generation algorithms grouped by purpose. */
const data_AlgorithmsByType = deepFreeze({
    /** Algorithms that produce passwords */
    [data_Type.password]: [Algorithm.password, Algorithm.passphrase],
    /** Algorithms that produce usernames */
    [data_Type.username]: [Algorithm.username],
    /** Algorithms that produce email addresses */
    [data_Type.email]: [Algorithm.catchall, Algorithm.plusAddress],
});

;// ../../libs/common/src/tools/integration/integration-context.ts

/** Utilities for processing integration settings */
class IntegrationContext {
    /** Instantiates an integration context
     *  @param metadata - defines integration capabilities
     *  @param i18n - localizes error messages
     */
    constructor(metadata, settings, i18n) {
        this.metadata = metadata;
        this.settings = settings;
        this.i18n = i18n;
    }
    /** Lookup the integration's baseUrl
     *  @returns the baseUrl for the API's integration point.
     *   - By default this is defined by the metadata
     *   - When a service allows self-hosting, this can be supplied by `settings`.
     *  @throws a localized error message when a base URL is neither defined by the metadata or
     *   supplied by an argument.
     */
    baseUrl() {
        var _a, _b;
        // normalize baseUrl
        const setting = (_a = (this.settings && "baseUrl" in this.settings
            ? this.settings.baseUrl
            : undefined)) !== null && _a !== void 0 ? _a : "";
        let result = "";
        // look up definition
        if (this.metadata.selfHost === "always") {
            result = setting;
        }
        else if (this.metadata.selfHost === "never" || setting.length <= 0) {
            result = (_b = this.metadata.baseUrl) !== null && _b !== void 0 ? _b : "";
        }
        else {
            result = setting;
        }
        // postconditions
        if (result === "") {
            const error = this.i18n.t("forwarderNoUrl", this.metadata.name);
            throw error;
        }
        return result;
    }
    /** look up a service API's authentication token
     *  @param options.base64 when `true`, base64 encodes the result. Defaults to `false`.
     *  @param options.suffix a string to append to the token. Defaults to empty.
     *  @returns the user's authentication token
     *  @throws a localized error message when the token is invalid.
     *  @remarks the string is thrown for backwards compatibility
     */
    authenticationToken(options = null) {
        var _a, _b;
        // normalize `token` then assert it has a value
        let token = "token" in this.settings ? ((_a = this.settings.token) !== null && _a !== void 0 ? _a : "") : "";
        if (token === "") {
            const error = this.i18n.t("forwaderInvalidToken", this.metadata.name);
            throw error;
        }
        // if a suffix exists, it needs to be included before encoding
        token += (_b = options === null || options === void 0 ? void 0 : options.suffix) !== null && _b !== void 0 ? _b : "";
        if (options === null || options === void 0 ? void 0 : options.base64) {
            token = utils_Utils.fromUtf8ToB64(token);
        }
        return token;
    }
    /** look up the website the integration is working with.
     *  @param request supplies information about the state of the extension site
     *  @param options optional parameters
     *  @param options.extractHostname when `true`, tries to extract the hostname from the website URL, returns full URL otherwise
     *  @param options.maxLength limits the length of the return value
     *  @returns The website or an empty string if a website isn't available
     *  @remarks `website` is usually supplied when generating a credential from the vault
     */
    website(request, options) {
        var _a, _b;
        let url = (_a = request.website) !== null && _a !== void 0 ? _a : "";
        if (options === null || options === void 0 ? void 0 : options.extractHostname) {
            url = (_b = utils_Utils.getHost(url)) !== null && _b !== void 0 ? _b : url;
        }
        return url.slice(0, options === null || options === void 0 ? void 0 : options.maxLength);
    }
    /** look up localized text indicating Bitwarden requested the forwarding address.
     *  @param request supplies information about the state of the extension site
     *  @param options optional parameters
     *  @param options.extractHostname when `true`, extracts the hostname from the website URL
     *  @param options.maxLength limits the length of the return value
     *  @returns localized text describing a generated forwarding address
     */
    generatedBy(request, options) {
        var _a;
        const website = this.website(request, { extractHostname: (_a = options === null || options === void 0 ? void 0 : options.extractHostname) !== null && _a !== void 0 ? _a : false });
        const descriptionId = website === "" ? "forwarderGeneratedBy" : "forwarderGeneratedByWithWebsite";
        const description = this.i18n.t(descriptionId, website);
        return description.slice(0, options === null || options === void 0 ? void 0 : options.maxLength);
    }
}

;// ../../libs/tools/generator/core/src/engine/forwarder-context.ts

/**
 * Surfaces contextual information to forwarder integrations.
 */
class forwarder_context_ForwarderContext extends IntegrationContext {
    /** Instantiates the context.
     * @param configuration of the forwarder this context assists
     * @param settings loaded from the forwarder's state
     * @param i18n localizes error handling
     */
    constructor(configuration, settings, i18n) {
        super(configuration, settings, i18n);
        this.configuration = configuration;
    }
    /** look up the domain part of an email address from the forwarder's settings.
     *  @returns a domain part of an email address
     *  @throws a localized error message when the domain isn't found.
     *  @remarks the string is thrown for backwards compatibility
     */
    emailDomain() {
        var _a;
        const domain = "domain" in this.settings ? ((_a = this.settings.domain) !== null && _a !== void 0 ? _a : "") : "";
        if (domain === "") {
            const error = this.i18n.t("forwarderNoDomain", this.configuration.name);
            throw error;
        }
        return domain;
    }
    /** look up a prefix applied to the email address from the forwarder's settings.
     *  @returns the prefix
     *  @throws a localized error message when the prefix isn't found.
     *  @remarks the string is thrown for backwards compatibility
     */
    emailPrefix() {
        var _a;
        const prefix = "prefix" in this.settings ? ((_a = this.settings.prefix) !== null && _a !== void 0 ? _a : "") : "";
        if (prefix === "") {
            const error = this.i18n.t("forwarderNoPrefix", this.configuration.name);
            throw error;
        }
        return prefix;
    }
    /** look up a localized error message indicating an account id is required
     *  but wasn't found.
     *  @remarks this returns a string instead of throwing it so that the
     *    user can decide upon control flow.
     */
    missingAccountIdCause() {
        return this.i18n.t("forwarderNoAccountId", this.configuration.name);
    }
}

;// ../../libs/tools/generator/core/src/types/generated-credential.ts
/** A credential generation result */
class generated_credential_GeneratedCredential {
    /**
     * Instantiates a generated credential
     * @param credential The value of the generated credential (e.g. a password)
     * @param category The type of credential
     * @param generationDate The date that the credential was generated.
     *   Numeric values should are interpreted using {@link Date.valueOf}
     *   semantics.
     * @param source traces the origin of the request that generated this credential.
     * @param website traces the website associated with the generated credential.
     */
    constructor(credential, 
    // FIXME: create a way to migrate the data stored in `category` to a new `type`
    //   field. The hard part: This requires the migration occur post-decryption.
    category, generationDate, source, website) {
        this.credential = credential;
        this.category = category;
        this.source = source;
        this.website = website;
        if (typeof generationDate === "number") {
            this.generationDate = new Date(generationDate);
        }
        else {
            this.generationDate = generationDate;
        }
    }
    /** Constructs a credential from its `toJSON` representation */
    static fromJSON(jsonValue) {
        return new generated_credential_GeneratedCredential(jsonValue.credential, jsonValue.category, jsonValue.generationDate);
    }
    /** Serializes a credential to a JSON-compatible object */
    toJSON() {
        // omits the source and website because they were introduced to solve
        // UI bugs and it's not yet known whether there's a desire to support
        // them in the generator history view.
        return {
            credential: this.credential,
            category: this.category,
            generationDate: this.generationDate.valueOf(),
        };
    }
}

;// ../../libs/tools/generator/core/src/engine/data.ts
function toCharacterSet(characters) {
    const set = characters.split("");
    return Object.freeze(set);
}
const SpecialCharacters = toCharacterSet("!@#$%^&*");
/** Sets of Ascii characters used for password generation */
const Ascii = Object.freeze({
    /** The full set of characters available to the generator */
    Full: Object.freeze({
        Uppercase: toCharacterSet("ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
        Lowercase: toCharacterSet("abcdefghijklmnopqrstuvwxyz"),
        Digit: toCharacterSet("0123456789"),
        Special: SpecialCharacters,
    }),
    /** All characters available to the generator that are not ambiguous. */
    Unmistakable: Object.freeze({
        Uppercase: toCharacterSet("ABCDEFGHJKLMNPQRSTUVWXYZ"),
        Lowercase: toCharacterSet("abcdefghijkmnopqrstuvwxyz"),
        Digit: toCharacterSet("23456789"),
        Special: SpecialCharacters,
    }),
});
/** Splits an email into a username, subaddress, and domain named group.
 * Subaddress is optional.
 */
const SUBADDRESS_PARSER = new RegExp("(?<username>[^@+]+)(?<subaddress>\\+.+)?(?<domain>@.+)");

;// ../../libs/tools/generator/core/src/engine/email-randomizer.ts
var email_randomizer_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore




/** Generation algorithms that produce randomized email addresses */
class EmailRandomizer {
    /** Instantiates the email randomizer
     *  @param random data source for random data
     */
    constructor(random) {
        this.random = random;
    }
    /** Appends a random set of characters as a subaddress
     *  @param email the email address used to generate a subaddress. If this address
     *    already contains a subaddress, the subaddress is extended.
     *  @param options.length the number of characters to append to the subaddress. Defaults to 8. If
     *    the length is <= 0, the function returns the input address.
     *  @returns a promise that resolves with the generated email address. If the provided address
     *    lacks a username (the part before the "@") or domain (the part after the "@"), the function
     *    returns the input address.
     */
    randomAsciiSubaddress(email, options) {
        return email_randomizer_awaiter(this, void 0, void 0, function* () {
            var _a, _b;
            let result = email !== null && email !== void 0 ? email : "";
            const subaddressLength = (_a = options === null || options === void 0 ? void 0 : options.length) !== null && _a !== void 0 ? _a : 8;
            if (subaddressLength < 1) {
                return result;
            }
            const parsed = SUBADDRESS_PARSER.exec(result);
            if (!parsed) {
                return result;
            }
            let subaddress = (_b = parsed.groups.subaddress) !== null && _b !== void 0 ? _b : "+";
            subaddress += yield this.random.chars(subaddressLength);
            result = `${parsed.groups.username}${subaddress}${parsed.groups.domain}`;
            return result;
        });
    }
    /** Creates a catchall address composed of random characters
     *  @param domain the domain part of the generated email address.
     *  @param options.length the number of characters to include in the catchall
     *    address. Defaults to 8.
     *  @returns a promise that resolves with the generated email address. If the domain
     *    is empty, resolves to null instead.
     */
    randomAsciiCatchall(domain, options) {
        return email_randomizer_awaiter(this, void 0, void 0, function* () {
            var _a;
            const emailDomain = (domain === null || domain === void 0 ? void 0 : domain.startsWith("@")) ? domain.substring(1, Infinity) : (domain !== null && domain !== void 0 ? domain : "");
            if (emailDomain.length < 1) {
                return null;
            }
            const length = (_a = options === null || options === void 0 ? void 0 : options.length) !== null && _a !== void 0 ? _a : 8;
            if (length < 1) {
                return null;
            }
            const catchall = yield this.random.chars(length);
            const result = `${catchall}@${domain}`;
            return result;
        });
    }
    /** Creates a catchall address composed of random words
     *  @param domain the domain part of the generated email address.
     *  @param options.numberOfWords the number of words to include in the catchall
     *    address. Defaults to 1.
     *  @param options.words selects words from the provided wordlist. Defaults to
     *    the EFF "5-dice" list.
     *  @returns a promise that resolves with the generated email address.
     */
    randomWordsCatchall(domain, options) {
        return email_randomizer_awaiter(this, void 0, void 0, function* () {
            var _a, _b;
            const emailDomain = (domain === null || domain === void 0 ? void 0 : domain.startsWith("@")) ? domain.substring(1, Infinity) : (domain !== null && domain !== void 0 ? domain : "");
            if (emailDomain.length < 1) {
                return null;
            }
            const numberOfWords = (_a = options === null || options === void 0 ? void 0 : options.numberOfWords) !== null && _a !== void 0 ? _a : 1;
            if (numberOfWords < 1) {
                return null;
            }
            const wordList = (_b = options === null || options === void 0 ? void 0 : options.words) !== null && _b !== void 0 ? _b : EFFLongWordList;
            const words = [];
            for (let i = 0; i < numberOfWords; i++) {
                // camelCase the words for legibility
                words[i] = yield this.random.pickWord(wordList, { titleCase: i !== 0 });
            }
            const result = `${words.join("")}@${domain}`;
            return result;
        });
    }
    generate(request, settings) {
        return email_randomizer_awaiter(this, void 0, void 0, function* () {
            if (isCatchallGenerationOptions(settings)) {
                const email = yield this.randomAsciiCatchall(settings.catchallDomain);
                return new generated_credential_GeneratedCredential(email, data_Type.email, Date.now(), request.source, request.website);
            }
            else if (isSubaddressGenerationOptions(settings)) {
                const email = yield this.randomAsciiSubaddress(settings.subaddressEmail);
                return new generated_credential_GeneratedCredential(email, data_Type.email, Date.now(), request.source, request.website);
            }
            throw new Error("Invalid settings received by generator.");
        });
    }
}
function isCatchallGenerationOptions(settings) {
    return "catchallDomain" in (settings !== null && settings !== void 0 ? settings : {});
}
function isSubaddressGenerationOptions(settings) {
    return "subaddressEmail" in (settings !== null && settings !== void 0 ? settings : {});
}

;// ../../libs/tools/generator/core/src/engine/email-calculator.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

/** Generation algorithms that produce deterministic email addresses */
class EmailCalculator {
    /**
     * Appends appendText to the subaddress of an email address.
     * @param appendText  The calculation fails if this is shorter than 1 character
     *   long, undefined, or null.
     * @param email the email address to alter.
     * @returns `email` with `appendText` added to its subaddress (the part
     *   following the "+"). If there is no subaddress, a subaddress is created.
     *   If the email address fails to parse, it is returned unaltered.
     */
    appendToSubaddress(appendText, email) {
        var _a;
        let result = (email !== null && email !== void 0 ? email : "").trim();
        const suffix = (appendText !== null && appendText !== void 0 ? appendText : "").trim();
        if (suffix.length < 1) {
            return result;
        }
        const parsed = SUBADDRESS_PARSER.exec(result);
        if (!parsed) {
            return result;
        }
        const subaddress = ((_a = parsed.groups.subaddress) !== null && _a !== void 0 ? _a : "+") + suffix;
        result = `${parsed.groups.username}${subaddress}${parsed.groups.domain}`;
        return result;
    }
    /**
     * Derives an email address from a username and domain name.
     * @param username the username part of the email address. The calculation fails if this is
     *   shorter than 1 character long, undefined, or null.
     * @param domain the domain part of the email address. The calculation fails if this is empty,
     *   undefined, or null.
     * @returns an email address or `null` if the calculation fails.
     */
    concatenate(username, domain) {
        const emailDomain = (domain === null || domain === void 0 ? void 0 : domain.startsWith("@")) ? domain.substring(1, Infinity) : (domain !== null && domain !== void 0 ? domain : "");
        if (emailDomain.length < 1) {
            return null;
        }
        const emailWebsite = username !== null && username !== void 0 ? username : "";
        if (emailWebsite.length < 1) {
            return null;
        }
        const result = `${emailWebsite}@${emailDomain}`;
        return result;
    }
}

;// ../../libs/tools/generator/core/src/util.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


/** construct a method that outputs a copy of `defaultValue` as an observable. */
function observe$PerUserId(create) {
    const _subjects = new Map();
    return (key) => {
        let value = _subjects.get(key);
        if (value === undefined) {
            const initialValue = create();
            value = new external_rxjs_namespaceObject.BehaviorSubject(Object.assign({}, initialValue));
            _subjects.set(key, value);
        }
        return value.asObservable();
    };
}
/** construct a method that caches user-specific states by userid. */
function sharedByUserId(create) {
    const _subjects = new Map();
    return (key) => {
        let value = _subjects.get(key);
        if (value === undefined) {
            value = create(key);
            _subjects.set(key, value);
        }
        return value;
    };
}
/** construct a method that loads a user-specific state from the provider. */
function sharedStateByUserId(key, provider) {
    return (id) => provider.getUser(id, key);
}
/** returns the sum of items in the list. */
const sum = (...items) => (items !== null && items !== void 0 ? items : []).reduce((sum, current) => sum + (current !== null && current !== void 0 ? current : 0), 0);
/* converts password generation option sets, which are defined by
 * an "enabled" and "quantity" parameter, to the password engine's
 * parameters, which represent disabled options as `undefined`
 * properties.
 */
function optionsToRandomAsciiRequest(options) {
    var _a, _b;
    // helper for processing common option sets
    function process(
    // values read from the options
    enabled, quantity, 
    // value used if an option is missing
    defaultEnabled, defaultQuantity) {
        const isEnabled = enabled !== null && enabled !== void 0 ? enabled : defaultEnabled;
        const actualQuantity = quantity !== null && quantity !== void 0 ? quantity : defaultQuantity;
        const result = isEnabled ? actualQuantity : undefined;
        return result;
    }
    const request = {
        uppercase: process(options.uppercase, options.minUppercase, DefaultPasswordGenerationOptions.uppercase, DefaultPasswordGenerationOptions.minUppercase),
        lowercase: process(options.lowercase, options.minLowercase, DefaultPasswordGenerationOptions.lowercase, DefaultPasswordGenerationOptions.minLowercase),
        digits: process(options.number, options.minNumber, DefaultPasswordGenerationOptions.number, DefaultPasswordGenerationOptions.minNumber),
        special: process(options.special, options.minSpecial, DefaultPasswordGenerationOptions.special, DefaultPasswordGenerationOptions.minSpecial),
        ambiguous: (_a = options.ambiguous) !== null && _a !== void 0 ? _a : DefaultPasswordGenerationOptions.ambiguous,
        all: 0,
    };
    // engine represents character sets as "include only"; you assert how many all
    // characters there can be rather than a total length. This conversion has
    // the character classes win, so that the result is always consistent with policy
    // minimums.
    const required = sum(request.uppercase, request.lowercase, request.digits, request.special);
    const remaining = ((_b = options.length) !== null && _b !== void 0 ? _b : 0) - required;
    request.all = Math.max(remaining, 0);
    return request;
}
/* converts passphrase generation option sets to the eff word list request
 */
function optionsToEffWordListRequest(options) {
    var _a, _b, _c, _d;
    const requestWords = (_a = options.numWords) !== null && _a !== void 0 ? _a : DefaultPassphraseGenerationOptions.numWords;
    const request = {
        numberOfWords: Math.max(requestWords, DefaultPassphraseBoundaries.numWords.min),
        capitalize: (_b = options.capitalize) !== null && _b !== void 0 ? _b : DefaultPassphraseGenerationOptions.capitalize,
        number: (_c = options.includeNumber) !== null && _c !== void 0 ? _c : DefaultPassphraseGenerationOptions.includeNumber,
        separator: (_d = options.wordSeparator) !== null && _d !== void 0 ? _d : DefaultPassphraseGenerationOptions.wordSeparator,
    };
    return request;
}
function util_equivalent(lhs, rhs) {
    var _a, _b;
    if (lhs.constraints.policyInEffect !== rhs.constraints.policyInEffect) {
        return false;
    }
    // safe because `Constraints<T>` shares keys with `T`
    const keys = Object.keys(lhs.constraints);
    // use `for` loop so that `equivalent` can return as soon as the constraints
    // differ. Using `array.xyz` would evaluate the whole key list eagerly
    for (const k of keys) {
        if (!(k in rhs.constraints)) {
            return false;
        }
        const lhsConstraints = (_a = lhs.constraints[k]) !== null && _a !== void 0 ? _a : {};
        const rhsConstraints = (_b = rhs.constraints[k]) !== null && _b !== void 0 ? _b : {};
        const innerKeys = Object.keys(lhsConstraints);
        if (innerKeys.some((k) => lhsConstraints[k] !== rhsConstraints[k])) {
            return false;
        }
    }
    return true;
}

;// ../../libs/tools/generator/core/src/engine/password-randomizer.ts
var password_randomizer_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore





/** Generation algorithms that produce randomized secrets */
class PasswordRandomizer {
    /** Instantiates the password randomizer
     *  @param randomizer data source for random data
     */
    constructor(randomizer, currentTime) {
        this.randomizer = randomizer;
        this.currentTime = currentTime;
    }
    /** create a password from ASCII codepoints
     *  @param request refines the generated password
     *  @returns a promise that completes with the generated password
     */
    randomAscii(request) {
        return password_randomizer_awaiter(this, void 0, void 0, function* () {
            // randomize character sets
            const sets = toAsciiSets(request);
            const shuffled = yield this.randomizer.shuffle(sets);
            // generate password
            const generating = shuffled.flatMap((set) => this.randomizer.pick(set));
            const generated = yield Promise.all(generating);
            const result = generated.join("");
            return result;
        });
    }
    /** create a passphrase from the EFF's "5 dice" word list
     *  @param request refines the generated passphrase
     * @returns a promise that completes with the generated passphrase
     */
    randomEffLongWords(request) {
        return password_randomizer_awaiter(this, void 0, void 0, function* () {
            // select which word gets the number, if any
            let luckyNumber = -1;
            if (request.number) {
                luckyNumber = yield this.randomizer.uniform(0, request.numberOfWords - 1);
            }
            // generate the passphrase
            const wordList = new Array(request.numberOfWords);
            for (let i = 0; i < request.numberOfWords; i++) {
                const word = yield this.randomizer.pickWord(EFFLongWordList, {
                    titleCase: request.capitalize,
                    number: i === luckyNumber,
                });
                wordList[i] = word;
            }
            return wordList.join(request.separator);
        });
    }
    generate(request, settings) {
        return password_randomizer_awaiter(this, void 0, void 0, function* () {
            if (isPasswordGenerationOptions(settings)) {
                const req = optionsToRandomAsciiRequest(settings);
                const password = yield this.randomAscii(req);
                return new generated_credential_GeneratedCredential(password, data_Type.password, this.currentTime(), request.source, request.website);
            }
            else if (isPassphraseGenerationOptions(settings)) {
                const req = optionsToEffWordListRequest(settings);
                const passphrase = yield this.randomEffLongWords(req);
                return new generated_credential_GeneratedCredential(passphrase, data_Type.password, this.currentTime(), request.source, request.website);
            }
            throw new Error("Invalid settings received by generator.");
        });
    }
}
function isPasswordGenerationOptions(settings) {
    return "length" in (settings !== null && settings !== void 0 ? settings : {});
}
function isPassphraseGenerationOptions(settings) {
    return "numWords" in (settings !== null && settings !== void 0 ? settings : {});
}
// given a generator request, convert each of its `number | undefined` properties
// to an array of character sets, one for each property. The transformation is
// deterministic.
function toAsciiSets(request) {
    // allocate an array and initialize each cell with a fixed value
    function allocate(size, value) {
        const data = new Array(size > 0 ? size : 0);
        data.fill(value, 0, size);
        return data;
    }
    const allSet = [];
    const active = request.ambiguous ? Ascii.Full : Ascii.Unmistakable;
    const parts = [];
    if (request.uppercase !== undefined) {
        parts.push(...allocate(request.uppercase, active.Uppercase));
        allSet.push(...active.Uppercase);
    }
    if (request.lowercase !== undefined) {
        parts.push(...allocate(request.lowercase, active.Lowercase));
        allSet.push(...active.Lowercase);
    }
    if (request.digits !== undefined) {
        parts.push(...allocate(request.digits, active.Digit));
        allSet.push(...active.Digit);
    }
    if (request.special !== undefined) {
        parts.push(...allocate(request.special, active.Special));
        allSet.push(...active.Special);
    }
    parts.push(...allocate(request.all, allSet));
    return parts;
}

;// ../../libs/tools/generator/core/src/engine/sdk-password-randomizer.ts
var sdk_password_randomizer_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};


/** Generation algorithms that produce randomized secrets by calling on functionality from the SDK */
class SdkPasswordRandomizer {
    /** Instantiates the password randomizer
     *  @param client access to SDK client to call upon password/passphrase generation
     *  @param currentTime gets the current datetime in epoch time
     */
    constructor(client, currentTime) {
        this.client = client;
        this.currentTime = currentTime;
    }
    generate(request, settings) {
        return sdk_password_randomizer_awaiter(this, void 0, void 0, function* () {
            if (sdk_password_randomizer_isPasswordGenerationOptions(settings)) {
                const password = yield this.client.generator().password(convertPasswordRequest(settings));
                return new generated_credential_GeneratedCredential(password, data_Type.password, this.currentTime(), request.source, request.website);
            }
            else if (sdk_password_randomizer_isPassphraseGenerationOptions(settings)) {
                const passphrase = yield this.client
                    .generator()
                    .passphrase(convertPassphraseRequest(settings));
                return new generated_credential_GeneratedCredential(passphrase, data_Type.password, this.currentTime(), request.source, request.website);
            }
            throw new Error("Invalid settings received by generator.");
        });
    }
}
function convertPasswordRequest(settings) {
    return {
        lowercase: settings.lowercase,
        uppercase: settings.uppercase,
        numbers: settings.number,
        special: settings.special,
        length: settings.length,
        avoidAmbiguous: settings.ambiguous,
        minLowercase: settings.minLowercase,
        minUppercase: settings.minUppercase,
        minNumber: settings.minNumber,
        minSpecial: settings.minSpecial,
    };
}
function convertPassphraseRequest(settings) {
    return {
        numWords: settings.numWords,
        wordSeparator: settings.wordSeparator,
        capitalize: settings.capitalize,
        includeNumber: settings.includeNumber,
    };
}
function sdk_password_randomizer_isPasswordGenerationOptions(settings) {
    return "length" in (settings !== null && settings !== void 0 ? settings : {});
}
function sdk_password_randomizer_isPassphraseGenerationOptions(settings) {
    return "numWords" in (settings !== null && settings !== void 0 ? settings : {});
}

;// ../../libs/tools/generator/core/src/engine/username-randomizer.ts
var username_randomizer_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};


/** The number of digits used when generating an Eff username with a number. */
const NUMBER_OF_DIGITS = 4;
/** Generation algorithms that produce randomized usernames */
class UsernameRandomizer {
    /** Instantiates the username randomizer
     *  @param random data source for random data
     */
    constructor(random) {
        this.random = random;
    }
    /** Creates a username composed of random words
     *  @param request parameters to which the generated username conforms
     *  @returns a promise that resolves with the generated username.
     */
    randomWords(request) {
        return username_randomizer_awaiter(this, void 0, void 0, function* () {
            var _a, _b, _c;
            const numberOfWords = (_a = request === null || request === void 0 ? void 0 : request.numberOfWords) !== null && _a !== void 0 ? _a : 1;
            if (numberOfWords < 1) {
                return "";
            }
            const digits = Math.max((_b = request === null || request === void 0 ? void 0 : request.digits) !== null && _b !== void 0 ? _b : 0, 0);
            let selectCase = (_) => false;
            if ((request === null || request === void 0 ? void 0 : request.casing) === "camelCase") {
                selectCase = (i) => i !== 0;
            }
            else if ((request === null || request === void 0 ? void 0 : request.casing) === "TitleCase") {
                selectCase = (_) => true;
            }
            const wordList = (_c = request === null || request === void 0 ? void 0 : request.words) !== null && _c !== void 0 ? _c : EFFLongWordList;
            const parts = [];
            for (let i = 0; i < numberOfWords; i++) {
                const word = yield this.random.pickWord(wordList, { titleCase: selectCase(i) });
                parts.push(word);
            }
            for (let i = 0; i < digits; i++) {
                const digit = yield this.random.uniform(0, 9);
                parts.push(digit.toString());
            }
            const result = parts.join("");
            return result;
        });
    }
    generate(request, settings) {
        return username_randomizer_awaiter(this, void 0, void 0, function* () {
            if (isEffUsernameGenerationOptions(settings)) {
                const username = yield this.randomWords({
                    digits: settings.wordIncludeNumber ? NUMBER_OF_DIGITS : 0,
                    casing: settings.wordCapitalize ? "TitleCase" : "lowercase",
                });
                return new generated_credential_GeneratedCredential(username, "username", Date.now(), request.source, request.website);
            }
            throw new Error("Invalid settings received by generator.");
        });
    }
}
function isEffUsernameGenerationOptions(settings) {
    return "wordIncludeNumber" in (settings !== null && settings !== void 0 ? settings : {});
}

;// ../../libs/tools/generator/core/src/engine/index.ts









;// ../../libs/tools/generator/core/src/policies/catchall-constraints.ts
/** Parses the domain part of an email address
 */
const DOMAIN_PARSER = new RegExp("[^@]+@(?<domain>.+)");
/** A constraint that sets the catchall domain using a fixed email address */
class CatchallConstraints {
    /** Creates a catchall constraints
     * @param email - the email address containing the domain.
     */
    constructor(email) {
        var _a;
        this.constraints = {};
        if (!email) {
            this.domain = "";
            return;
        }
        const parsed = DOMAIN_PARSER.exec(email);
        if (parsed && ((_a = parsed.groups) === null || _a === void 0 ? void 0 : _a.domain)) {
            this.domain = parsed.groups.domain;
        }
    }
    adjust(state) {
        var _a;
        const currentDomain = ((_a = state.catchallDomain) !== null && _a !== void 0 ? _a : "").trim();
        if (currentDomain !== "") {
            return state;
        }
        const options = Object.assign({}, state);
        options.catchallDomain = this.domain;
        return options;
    }
    fix(state) {
        return state;
    }
}

;// ../../libs/tools/generator/core/src/metadata/email/catchall.ts






const catchall = deepFreeze({
    id: Algorithm.catchall,
    type: data_Type.email,
    weight: 210,
    i18nKeys: {
        name: "catchallEmail",
        description: "catchallEmailDesc",
        credentialType: "email",
        generateCredential: "generateEmail",
        credentialGenerated: "emailGenerated",
        copyCredential: "copyEmail",
        useCredential: "useThisEmail",
    },
    capabilities: {
        autogenerate: true,
        fields: [],
    },
    engine: {
        create(dependencies) {
            return new EmailRandomizer(dependencies.randomizer);
        },
    },
    profiles: {
        [data_Profile.account]: {
            type: "core",
            storage: {
                key: "catchallGeneratorSettings",
                target: "object",
                format: "plain",
                classifier: new PublicClassifier([
                    "catchallType",
                    "catchallDomain",
                ]),
                state: GENERATOR_DISK,
                initial: {
                    catchallType: "random",
                    catchallDomain: "",
                },
                options: {
                    deserializer: (value) => value,
                    clearOn: ["logout"],
                },
            },
            constraints: {
                default: { catchallDomain: { minLength: 1 } },
                create(_policies, context) {
                    var _a;
                    return new CatchallConstraints((_a = context.email) !== null && _a !== void 0 ? _a : "");
                },
            },
        },
    },
});
/* harmony default export */ const email_catchall = (catchall);

;// ../../libs/tools/generator/core/src/policies/subaddress-constraints.ts
/** A constraint that sets the subaddress email using a fixed email address */
class SubaddressConstraints {
    /** Creates a catchall constraints
     * @param email - the email address containing the domain.
     */
    constructor(email) {
        this.email = email;
        this.constraints = {};
        if (!email) {
            this.email = "";
        }
    }
    adjust(state) {
        var _a;
        const currentDomain = ((_a = state.subaddressEmail) !== null && _a !== void 0 ? _a : "").trim();
        if (currentDomain !== "") {
            return state;
        }
        const options = Object.assign({}, state);
        options.subaddressEmail = this.email;
        return options;
    }
    fix(state) {
        return state;
    }
}

;// ../../libs/tools/generator/core/src/metadata/email/plus-address.ts






const plusAddress = deepFreeze({
    id: Algorithm.plusAddress,
    type: data_Type.email,
    weight: 200,
    i18nKeys: {
        name: "plusAddressedEmail",
        description: "plusAddressedEmailDesc",
        credentialType: "email",
        generateCredential: "generateEmail",
        credentialGenerated: "emailGenerated",
        copyCredential: "copyEmail",
        useCredential: "useThisEmail",
    },
    capabilities: {
        autogenerate: true,
        fields: [],
    },
    engine: {
        create(dependencies) {
            return new EmailRandomizer(dependencies.randomizer);
        },
    },
    profiles: {
        [data_Profile.account]: {
            type: "core",
            storage: {
                key: "subaddressGeneratorSettings",
                target: "object",
                format: "plain",
                classifier: new PublicClassifier([
                    "subaddressType",
                    "subaddressEmail",
                ]),
                state: GENERATOR_DISK,
                initial: {
                    subaddressType: "random",
                    subaddressEmail: "",
                },
                options: {
                    deserializer(value) {
                        return value;
                    },
                    clearOn: ["logout"],
                },
            },
            constraints: {
                default: {},
                create(_policy, context) {
                    var _a;
                    return new SubaddressConstraints((_a = context.email) !== null && _a !== void 0 ? _a : "");
                },
            },
        },
    },
});
/* harmony default export */ const plus_address = (plusAddress);

;// ../../libs/tools/generator/core/src/policies/default-policy-evaluator.ts
/** A policy evaluator that does not apply any policy */
class DefaultPolicyEvaluator {
    /** {@link PolicyEvaluator.policy} */
    get policy() {
        return {};
    }
    /** {@link PolicyEvaluator.policyInEffect} */
    get policyInEffect() {
        return false;
    }
    /** {@link PolicyEvaluator.applyPolicy} */
    applyPolicy(options) {
        return options;
    }
    /** {@link PolicyEvaluator.sanitize} */
    sanitize(options) {
        return options;
    }
}

;// ../../libs/tools/generator/core/src/policies/constraints.ts

const Zero = { min: 0, max: 0 };
const AtLeastOne = { min: 1 };
const RequiresTrue = { requiredValue: true };
/** Ensures the minimum and maximum bounds of a constraint are at least as large as the
 *  combined minimum bounds of `dependencies`.
 *  @param current the constraint extended by the combinator.
 *  @param dependencies the constraints summed to determine the bounds of `current`.
 *  @returns a copy of `current` with the new bounds applied.
 *
 */
function atLeastSum(current, dependencies) {
    var _a;
    // length must be at least as long as the required character set
    const minConsistentLength = sum(...dependencies.map((c) => c === null || c === void 0 ? void 0 : c.min));
    const minLength = Math.max((_a = current === null || current === void 0 ? void 0 : current.min) !== null && _a !== void 0 ? _a : 0, minConsistentLength);
    const length = atLeast(minLength, current);
    return length;
}
/** Extends a constraint with a readonly field.
 *  @param readonly Adds a readonly field when this is `true`.
 *  @param constraint the constraint extended by the combinator.
 *  @returns a copy of `constraint` with the readonly constraint applied as-needed.
 */
function maybeReadonly(readonly, constraint) {
    if (!readonly) {
        return constraint;
    }
    const result = Object.assign({}, constraint !== null && constraint !== void 0 ? constraint : {});
    result.readonly = true;
    return result;
}
/** Conditionally enables a constraint.
 *  @param enabled the condition to evaluate
 *  @param constraint the condition to conditionally enable
 *  @returns `constraint` when `enabled` is true. Otherwise returns `undefined.
 */
function maybe(enabled, constraint) {
    return enabled ? constraint : undefined;
}
// copies `constraint`; ensures both bounds >= value
/** Ensures the boundaries of a constraint are at least equal to the minimum.
 *  @param minimum the lower bound of the constraint. When this is `undefined` or `null`,
 *   the method returns `constraint`.
 *  @param constraint the constraint to evaluate. When this is `undefined` or `null`,
 *   the method creates a new constraint.
 *  @returns a copy of `constraint`. When `minimum` has a value, the returned constraint
 *   always includes a minimum bound. When `constraint` has a maximum defined, both
 *   its minimum and maximum are checked against `minimum`.
 */
function atLeast(minimum, constraint) {
    var _a;
    if (minimum === undefined || minimum === null) {
        return constraint;
    }
    const atLeast = Object.assign({}, (constraint !== null && constraint !== void 0 ? constraint : {}));
    atLeast.min = Math.max((_a = atLeast.min) !== null && _a !== void 0 ? _a : -Infinity, minimum);
    if ("max" in atLeast) {
        atLeast.max = Math.max(atLeast.max, minimum);
    }
    return atLeast;
}
/** Ensures a value falls within the minimum and maximum boundaries of a constraint.
 *  @param value the value to check. Nullish values are coerced to 0.
 *  @param constraint the constraint to evaluate against.
 *  @returns If the value is below the minimum constraint, the minimum bound is
 *   returned. If the value is above the maximum constraint, the maximum bound is
 *   returned. Otherwise, the value is returned.
 */
function fitToBounds(value, constraint) {
    if (!constraint) {
        return value;
    }
    const { min, max } = constraint;
    const withUpperBound = Math.min(value !== null && value !== void 0 ? value : 0, max !== null && max !== void 0 ? max : Infinity);
    const withLowerBound = Math.max(withUpperBound, min !== null && min !== void 0 ? min : -Infinity);
    return withLowerBound;
}
/** Fits the length of a string within the minimum and maximum length boundaries
 *  of a constraint.
 *  @param value the value to check. Nullish values are coerced to the empty string.
 *  @param constraint the constraint to evaluate against.
 *  @param options.fillString a string to fill values from. Defaults to a space.
 *   When fillString contains multiple characters, each is filled in order. The
 *   fill string repeats when it gets to the end of the string and there are
 *   more characters to fill.
 *  @returns If the value is below the required length, returns a copy padded
 *   by the fillString. If the value is above the required length, returns a copy
 *   padded to the maximum length.
 * */
function fitLength(value, constraint, options) {
    if (!constraint) {
        return value;
    }
    const { minLength, maxLength } = constraint;
    const { fillString } = options !== null && options !== void 0 ? options : { fillString: " " };
    const trimmed = (value !== null && value !== void 0 ? value : "").slice(0, maxLength !== null && maxLength !== void 0 ? maxLength : Infinity);
    const result = trimmed.padEnd(minLength !== null && minLength !== void 0 ? minLength : trimmed.length, fillString);
    return result;
}
/** Enforces a readonly field has a required value.
 *  @param value the value to check.
 *  @param constraint the constraint to evaluate against.
 *  @returns If the constraint's readonly field is `true`, returns the
 *   constraint's required value or `undefined` if none is specified.
 *   Otherwise returns the value.
 *  @remarks This method can be used to ensure a conditionally-calculated
 *   field becomes undefined. Simply specify `readonly` without a `requiredValue`
 *   then use `??` to perform the calculation.
 */
function enforceConstant(value, constraint) {
    if (constraint === null || constraint === void 0 ? void 0 : constraint.readonly) {
        return constraint.requiredValue;
    }
    else {
        return value;
    }
}
/** Conditionally create a readonly true value.
 *  @param enabled When true, create the value.
 *  @returns When enabled is true, a readonly constraint with a constant value
 *  of `true`. Otherwise returns `undefined`.
 */
function readonlyTrueWhen(enabled) {
    const readonlyValue = maybeReadonly(enabled, RequiresTrue);
    const maybeReadonlyValue = maybe(enabled, readonlyValue);
    return maybeReadonlyValue;
}


;// ../../libs/tools/generator/core/src/policies/password-policy-constraints.ts


class PasswordPolicyConstraints {
    /** Creates a password policy constraints
     *  @param constraints Constraints derived from the policy and application-defined defaults
     */
    constructor(constraints) {
        this.constraints = constraints;
    }
    adjust(state) {
        // constrain values
        const result = Object.assign(Object.assign({}, (state !== null && state !== void 0 ? state : DefaultPasswordGenerationOptions)), { length: fitToBounds(state.length, this.constraints.length), lowercase: enforceConstant(state.lowercase, this.constraints.lowercase), uppercase: enforceConstant(state.uppercase, this.constraints.uppercase), number: enforceConstant(state.number, this.constraints.number), special: enforceConstant(state.special, this.constraints.special), minLowercase: fitToBounds(state.minLowercase, this.constraints.minLowercase), minUppercase: fitToBounds(state.minUppercase, this.constraints.minUppercase), minNumber: fitToBounds(state.minNumber, this.constraints.minNumber), minSpecial: fitToBounds(state.minSpecial, this.constraints.minSpecial) });
        // ensure include flags are consistent with the constrained values
        result.lowercase || (result.lowercase = state.minLowercase > 0);
        result.uppercase || (result.uppercase = state.minUppercase > 0);
        result.number || (result.number = state.minNumber > 0);
        result.special || (result.special = state.minSpecial > 0);
        // when all flags are disabled, enable a few
        const anyEnabled = [result.lowercase, result.uppercase, result.number, result.special].some((flag) => flag);
        if (!anyEnabled) {
            result.lowercase = true;
            result.uppercase = true;
        }
        return result;
    }
    fix(state) {
        return state;
    }
}

;// ../../libs/tools/generator/core/src/policies/dynamic-password-policy-constraints.ts


/** Creates state constraints by blending policy and password settings. */
class DynamicPasswordPolicyConstraints {
    /** Instantiates the object.
     *  @param policy the password policy to enforce. This cannot be
     *  `null` or `undefined`.
     */
    constructor(policy, defaults) {
        this.defaults = defaults;
        const minLowercase = maybe(policy.useLowercase, AtLeastOne);
        const minUppercase = maybe(policy.useUppercase, AtLeastOne);
        const minNumber = atLeast(policy.numberCount || (policy.useNumbers && AtLeastOne.min), defaults.minNumber);
        const minSpecial = atLeast(policy.specialCount || (policy.useSpecial && AtLeastOne.min), defaults.minSpecial);
        const baseLength = atLeast(policy.minLength, defaults.length);
        const subLengths = [minLowercase, minUppercase, minNumber, minSpecial];
        const length = atLeastSum(baseLength, subLengths);
        this.constraints = Object.freeze({
            policyInEffect: policyInEffect(policy, defaults),
            lowercase: readonlyTrueWhen(policy.useLowercase),
            uppercase: readonlyTrueWhen(policy.useUppercase),
            number: readonlyTrueWhen(policy.useNumbers),
            special: readonlyTrueWhen(policy.useSpecial),
            length,
            minLowercase,
            minUppercase,
            minNumber,
            minSpecial,
        });
    }
    calibrate(state) {
        var _a, _b, _c, _d, _e, _f, _g, _h;
        // decide which constraints are active
        const lowercase = state.lowercase || ((_a = this.constraints.lowercase) === null || _a === void 0 ? void 0 : _a.requiredValue) || false;
        const uppercase = state.uppercase || ((_b = this.constraints.uppercase) === null || _b === void 0 ? void 0 : _b.requiredValue) || false;
        const number = state.number || ((_c = this.constraints.number) === null || _c === void 0 ? void 0 : _c.requiredValue) || false;
        const special = state.special || ((_d = this.constraints.special) === null || _d === void 0 ? void 0 : _d.requiredValue) || false;
        // minimum constraints cannot `atLeast(state...) because doing so would force
        // the constrained value to only increase
        const constraints = Object.assign(Object.assign({}, this.constraints), { minLowercase: maybe(lowercase, (_e = this.constraints.minLowercase) !== null && _e !== void 0 ? _e : AtLeastOne), minUppercase: maybe(uppercase, (_f = this.constraints.minUppercase) !== null && _f !== void 0 ? _f : AtLeastOne), minNumber: (_g = maybe(number, this.constraints.minNumber)) !== null && _g !== void 0 ? _g : Zero, minSpecial: (_h = maybe(special, this.constraints.minSpecial)) !== null && _h !== void 0 ? _h : Zero });
        // lower bound of length must always at least fit its sub-lengths
        constraints.length = atLeastSum(this.constraints.length, [
            atLeast(state.minNumber, constraints.minNumber),
            atLeast(state.minSpecial, constraints.minSpecial),
            atLeast(state.minLowercase, constraints.minLowercase),
            atLeast(state.minUppercase, constraints.minUppercase),
        ]);
        const stateConstraints = new PasswordPolicyConstraints(constraints);
        return stateConstraints;
    }
}
function policyInEffect(policy, defaults) {
    const policies = [
        policy.useUppercase,
        policy.useLowercase,
        policy.useNumbers,
        policy.useSpecial,
        policy.minLength > defaults.length.min,
        policy.numberCount > defaults.minNumber.min,
        policy.specialCount > defaults.minSpecial.min,
    ];
    return policies.includes(true);
}

;// ../../libs/tools/generator/core/src/policies/passphrase-generator-options-evaluator.ts

/** Enforces policy for passphrase generation options.
 */
class PassphraseGeneratorOptionsEvaluator {
    /** Instantiates the evaluator.
     * @param policy The policy applied by the evaluator. When this conflicts with
     *               the defaults, the policy takes precedence.
     */
    constructor(policy) {
        function createBoundary(value, defaultBoundary) {
            const boundary = {
                min: Math.max(defaultBoundary.min, value),
                max: Math.max(defaultBoundary.max, value),
            };
            return boundary;
        }
        this.policy = structuredClone(policy);
        this.numWords = createBoundary(policy.minNumberWords, DefaultPassphraseBoundaries.numWords);
    }
    /** {@link PolicyEvaluator.policyInEffect} */
    get policyInEffect() {
        const policies = [
            this.policy.capitalize,
            this.policy.includeNumber,
            this.policy.minNumberWords > DefaultPassphraseBoundaries.numWords.min,
        ];
        return policies.includes(true);
    }
    /** Apply policy to the input options.
     *  @param options The options to build from. These options are not altered.
     *  @returns A new password generation request with policy applied.
     */
    applyPolicy(options) {
        function fitToBounds(value, boundaries) {
            const { min, max } = boundaries;
            const withUpperBound = Math.min(value !== null && value !== void 0 ? value : boundaries.min, max);
            const withLowerBound = Math.max(withUpperBound, min);
            return withLowerBound;
        }
        // apply policy overrides
        const capitalize = this.policy.capitalize || options.capitalize || false;
        const includeNumber = this.policy.includeNumber || options.includeNumber || false;
        // apply boundaries
        const numWords = fitToBounds(options.numWords, this.numWords);
        return Object.assign(Object.assign({}, options), { numWords,
            capitalize,
            includeNumber });
    }
    /** Ensures internal options consistency.
     *  @param options The options to cascade. These options are not altered.
     *  @returns A passphrase generation request with cascade applied.
     */
    sanitize(options) {
        var _a, _b;
        // ensure words are separated by a single character or the empty string
        const wordSeparator = options.wordSeparator === ""
            ? ""
            : ((_b = (_a = options.wordSeparator) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : DefaultPassphraseGenerationOptions.wordSeparator);
        return Object.assign(Object.assign({}, options), { wordSeparator });
    }
}

;// ../../libs/tools/generator/core/src/policies/passphrase-policy-constraints.ts


class PassphrasePolicyConstraints {
    /** Creates a passphrase policy constraints
     *  @param policy the password policy to enforce. This cannot be
     *  `null` or `undefined`.
     */
    constructor(policy, defaults) {
        this.policy = policy;
        this.defaults = defaults;
        this.constraints = {
            policyInEffect: passphrase_policy_constraints_policyInEffect(policy, defaults),
            wordSeparator: { minLength: 0, maxLength: 1 },
            capitalize: readonlyTrueWhen(policy.capitalize),
            includeNumber: readonlyTrueWhen(policy.includeNumber),
            numWords: atLeast(policy.minNumberWords, defaults.numWords),
        };
    }
    adjust(state) {
        const result = {
            wordSeparator: fitLength(state.wordSeparator, this.constraints.wordSeparator, {
                fillString: DefaultPassphraseGenerationOptions.wordSeparator,
            }),
            capitalize: enforceConstant(state.capitalize, this.constraints.capitalize),
            includeNumber: enforceConstant(state.includeNumber, this.constraints.includeNumber),
            numWords: fitToBounds(state.numWords, this.constraints.numWords),
        };
        return result;
    }
    fix(state) {
        return state;
    }
}
function passphrase_policy_constraints_policyInEffect(policy, defaults) {
    const policies = [
        policy.capitalize,
        policy.includeNumber,
        policy.minNumberWords > defaults.numWords.min,
    ];
    return policies.includes(true);
}

;// ../../libs/tools/generator/core/src/policies/password-generator-options-evaluator.ts

/** Enforces policy for password generation.
 */
class PasswordGeneratorOptionsEvaluator {
    // Constraints<PasswordGenerationOptions> compatibility
    get minNumber() {
        return this.minDigits;
    }
    get minSpecial() {
        return this.minSpecialCharacters;
    }
    /** Instantiates the evaluator.
     * @param policy The policy applied by the evaluator. When this conflicts with
     *               the defaults, the policy takes precedence.
     */
    constructor(policy) {
        function createBoundary(value, defaultBoundary) {
            const boundary = {
                min: Math.max(defaultBoundary.min, value),
                max: Math.max(defaultBoundary.max, value),
            };
            return boundary;
        }
        this.policy = structuredClone(policy);
        this.minDigits = createBoundary(policy.numberCount, DefaultPasswordBoundaries.minDigits);
        this.minSpecialCharacters = createBoundary(policy.specialCount, DefaultPasswordBoundaries.minSpecialCharacters);
        // the overall length should be at least as long as the sum of the minimums
        const minConsistentLength = this.minDigits.min + this.minSpecialCharacters.min;
        const minPolicyLength = policy.minLength > 0 ? policy.minLength : DefaultPasswordBoundaries.length.min;
        const minLength = Math.max(minPolicyLength, minConsistentLength, DefaultPasswordBoundaries.length.min);
        this.length = {
            min: minLength,
            max: Math.max(DefaultPasswordBoundaries.length.max, minLength),
        };
    }
    /** {@link PolicyEvaluator.policyInEffect} */
    get policyInEffect() {
        const policies = [
            this.policy.useUppercase,
            this.policy.useLowercase,
            this.policy.useNumbers,
            this.policy.useSpecial,
            this.policy.minLength > DefaultPasswordBoundaries.length.min,
            this.policy.numberCount > DefaultPasswordBoundaries.minDigits.min,
            this.policy.specialCount > DefaultPasswordBoundaries.minSpecialCharacters.min,
        ];
        return policies.includes(true);
    }
    /** {@link PolicyEvaluator.applyPolicy} */
    applyPolicy(options) {
        function fitToBounds(value, boundaries) {
            const { min, max } = boundaries;
            const withUpperBound = Math.min(value || 0, max);
            const withLowerBound = Math.max(withUpperBound, min);
            return withLowerBound;
        }
        // apply policy overrides
        const uppercase = this.policy.useUppercase || options.uppercase || false;
        const lowercase = this.policy.useLowercase || options.lowercase || false;
        // these overrides can cascade numeric fields to boolean fields
        const number = this.policy.useNumbers || options.number || options.minNumber > 0;
        const special = this.policy.useSpecial || options.special || options.minSpecial > 0;
        // apply boundaries; the boundaries can cascade boolean fields to numeric fields
        const length = fitToBounds(options.length, this.length);
        const minNumber = fitToBounds(options.minNumber, this.minDigits);
        const minSpecial = fitToBounds(options.minSpecial, this.minSpecialCharacters);
        return Object.assign(Object.assign({}, options), { length,
            uppercase,
            lowercase,
            number,
            minNumber,
            special,
            minSpecial });
    }
    /** {@link PolicyEvaluator.sanitize} */
    sanitize(options) {
        var _a;
        function cascade(enabled, value) {
            const enabledResult = enabled !== null && enabled !== void 0 ? enabled : value > 0;
            const valueResult = enabledResult ? value || 1 : 0;
            return [enabledResult, valueResult];
        }
        const [lowercase, minLowercase] = cascade(options.lowercase, options.minLowercase);
        const [uppercase, minUppercase] = cascade(options.uppercase, options.minUppercase);
        const [number, minNumber] = cascade(options.number, options.minNumber);
        const [special, minSpecial] = cascade(options.special, options.minSpecial);
        // minimums can only increase the length
        const minConsistentLength = minLowercase + minUppercase + minNumber + minSpecial;
        const minLength = Math.max(minConsistentLength, this.length.min);
        const length = Math.max((_a = options.length) !== null && _a !== void 0 ? _a : minLength, minLength);
        return Object.assign(Object.assign({}, options), { length,
            minLength,
            lowercase,
            minLowercase,
            uppercase,
            minUppercase,
            number,
            minNumber,
            special,
            minSpecial });
    }
}

;// ../../libs/tools/generator/core/src/policies/passphrase-least-privilege.ts

/** Reduces a policy into an accumulator by accepting the most restrictive
 *  values from each policy.
 *  @param acc the accumulator
 *  @param policy the policy to reduce
 *  @returns the most restrictive values between the policy and accumulator.
 */
function passphraseLeastPrivilege(acc, policy) {
    var _a;
    if (policy.type !== policy_type_enum_PolicyType.PasswordGenerator) {
        return acc;
    }
    return {
        minNumberWords: Math.max(acc.minNumberWords, (_a = policy.data.minNumberWords) !== null && _a !== void 0 ? _a : acc.minNumberWords),
        capitalize: policy.data.capitalize || acc.capitalize,
        includeNumber: policy.data.includeNumber || acc.includeNumber,
    };
}

;// ../../libs/tools/generator/core/src/policies/password-least-privilege.ts

/** Reduces a policy into an accumulator by accepting the most restrictive
 *  values from each policy.
 *  @param acc the accumulator
 *  @param policy the policy to reduce
 *  @returns the most restrictive values between the policy and accumulator.
 */
function passwordLeastPrivilege(acc, policy) {
    var _a, _b, _c;
    if (policy.type !== policy_type_enum_PolicyType.PasswordGenerator || !policy.enabled) {
        return acc;
    }
    return {
        minLength: Math.max(acc.minLength, (_a = policy.data.minLength) !== null && _a !== void 0 ? _a : acc.minLength),
        useUppercase: policy.data.useUpper || acc.useUppercase,
        useLowercase: policy.data.useLower || acc.useLowercase,
        useNumbers: policy.data.useNumbers || acc.useNumbers,
        numberCount: Math.max(acc.numberCount, (_b = policy.data.minNumbers) !== null && _b !== void 0 ? _b : acc.numberCount),
        useSpecial: policy.data.useSpecial || acc.useSpecial,
        specialCount: Math.max(acc.specialCount, (_c = policy.data.minSpecial) !== null && _c !== void 0 ? _c : acc.specialCount),
    };
}

;// ../../libs/tools/generator/core/src/policies/available-algorithms-policy.ts


/** Reduces policies to a set of available algorithms
 *  @param policies the policies to reduce
 *  @returns the resulting `AlgorithmAvailabilityPolicy`
 */
function available_algorithms_policy_availableAlgorithms(policies) {
    const overridePassword = policies
        .filter((policy) => policy.type === PolicyType.PasswordGenerator && policy.enabled)
        .reduce((type, policy) => { var _a; return (type === "password" ? type : ((_a = policy.data.overridePasswordType) !== null && _a !== void 0 ? _a : type)); }, null);
    const policy = [
        ...AlgorithmsByType[Type.email],
        ...AlgorithmsByType[Type.username],
    ];
    if (overridePassword) {
        policy.push(overridePassword);
    }
    else {
        policy.push(...AlgorithmsByType[Type.password]);
    }
    return policy;
}

;// ../../libs/tools/generator/core/src/policies/index.ts










;// ../../libs/tools/generator/core/src/metadata/password/eff-word-list.ts






const passphrase = {
    id: Algorithm.passphrase,
    type: data_Type.password,
    weight: 110,
    i18nKeys: {
        name: "passphrase",
        credentialType: "passphrase",
        generateCredential: "generatePassphrase",
        credentialGenerated: "passphraseGenerated",
        copyCredential: "copyPassphrase",
        useCredential: "useThisPassphrase",
    },
    capabilities: {
        autogenerate: true,
        fields: [],
    },
    engine: {
        create(dependencies) {
            if (dependencies.sdk == undefined) {
                return new PasswordRandomizer(dependencies.randomizer, dependencies.now);
            }
            return new SdkPasswordRandomizer(dependencies.sdk, dependencies.now);
        },
    },
    profiles: {
        [data_Profile.account]: {
            type: "core",
            storage: {
                key: "passphraseGeneratorSettings",
                target: "object",
                format: "plain",
                classifier: new PublicClassifier([
                    "numWords",
                    "wordSeparator",
                    "capitalize",
                    "includeNumber",
                ]),
                state: GENERATOR_DISK,
                initial: {
                    numWords: 6,
                    wordSeparator: "-",
                    capitalize: false,
                    includeNumber: false,
                },
                options: {
                    deserializer(value) {
                        return value;
                    },
                    clearOn: ["logout"],
                },
            },
            constraints: {
                type: policy_type_enum_PolicyType.PasswordGenerator,
                default: {
                    wordSeparator: { maxLength: 1 },
                    numWords: {
                        min: 3,
                        max: 20,
                        recommendation: 6,
                    },
                },
                create(policies, context) {
                    const initial = {
                        minNumberWords: 0,
                        capitalize: false,
                        includeNumber: false,
                    };
                    const policy = policies.reduce(passphraseLeastPrivilege, initial);
                    const constraints = new PassphrasePolicyConstraints(policy, context.defaultConstraints);
                    return constraints;
                },
            },
        },
    },
};
/* harmony default export */ const eff_word_list = (passphrase);

;// ../../libs/tools/generator/core/src/metadata/password/random-password.ts







const random_password_password = deepFreeze({
    id: Algorithm.password,
    type: data_Type.password,
    weight: 100,
    i18nKeys: {
        name: "password",
        generateCredential: "generatePassword",
        credentialGenerated: "passwordGenerated",
        credentialType: "password",
        copyCredential: "copyPassword",
        useCredential: "useThisPassword",
    },
    capabilities: {
        autogenerate: true,
        fields: [],
    },
    engine: {
        create(dependencies) {
            if (dependencies.sdk == undefined) {
                return new PasswordRandomizer(dependencies.randomizer, dependencies.now);
            }
            return new SdkPasswordRandomizer(dependencies.sdk, dependencies.now);
        },
    },
    profiles: {
        [data_Profile.account]: {
            type: "core",
            storage: {
                key: "passwordGeneratorSettings",
                target: "object",
                format: "plain",
                classifier: new PublicClassifier([
                    "length",
                    "ambiguous",
                    "uppercase",
                    "minUppercase",
                    "lowercase",
                    "minLowercase",
                    "number",
                    "minNumber",
                    "special",
                    "minSpecial",
                ]),
                state: GENERATOR_DISK,
                initial: {
                    length: 14,
                    ambiguous: true,
                    uppercase: true,
                    minUppercase: 1,
                    lowercase: true,
                    minLowercase: 1,
                    number: true,
                    minNumber: 1,
                    special: false,
                    minSpecial: 0,
                },
                options: {
                    deserializer(value) {
                        return value;
                    },
                    clearOn: ["logout"],
                },
            },
            constraints: {
                type: policy_type_enum_PolicyType.PasswordGenerator,
                default: {
                    length: {
                        min: 5,
                        max: 128,
                        recommendation: 14,
                    },
                    minNumber: {
                        min: 0,
                        max: 9,
                    },
                    minSpecial: {
                        min: 0,
                        max: 9,
                    },
                },
                create(policies, context) {
                    const initial = {
                        minLength: 0,
                        useUppercase: false,
                        useLowercase: false,
                        useNumbers: false,
                        numberCount: 0,
                        useSpecial: false,
                        specialCount: 0,
                    };
                    const policy = policies.reduce(passwordLeastPrivilege, initial);
                    const constraints = new DynamicPasswordPolicyConstraints(policy, context.defaultConstraints);
                    return constraints;
                },
            },
        },
    },
});
/* harmony default export */ const random_password = (random_password_password);

;// ../../libs/common/src/tools/state/identity-state-constraint.ts

// The constraints type shares the properties of the state,
// but never has any members
const EMPTY_CONSTRAINTS = new Proxy(Object.freeze({}), {
    get() {
        return {};
    },
});
/** A constraint that does nothing. */
class identity_state_constraint_IdentityConstraint {
    /** Instantiate the identity constraint */
    constructor() {
        this.constraints = EMPTY_CONSTRAINTS;
    }
    calibrate() {
        return this;
    }
    adjust(state) {
        return state;
    }
    fix(state) {
        return state;
    }
}
/** Emits a constraint that does not alter the input state. */
function unconstrained$() {
    const identity = new identity_state_constraint_IdentityConstraint();
    const constraints$ = new external_rxjs_namespaceObject.BehaviorSubject(identity);
    return constraints$;
}

;// ../../libs/tools/generator/core/src/metadata/username/eff-word-list.ts






const effWordList = deepFreeze({
    id: Algorithm.username,
    type: data_Type.username,
    weight: 400,
    i18nKeys: {
        name: "randomWord",
        credentialType: "username",
        generateCredential: "generateUsername",
        credentialGenerated: "usernameGenerated",
        copyCredential: "copyUsername",
        useCredential: "useThisUsername",
    },
    capabilities: {
        autogenerate: true,
        fields: [],
    },
    engine: {
        create(dependencies) {
            return new UsernameRandomizer(dependencies.randomizer);
        },
    },
    profiles: {
        [data_Profile.account]: {
            type: "core",
            storage: {
                key: "effUsernameGeneratorSettings",
                target: "object",
                format: "plain",
                classifier: new PublicClassifier([
                    "wordCapitalize",
                    "wordIncludeNumber",
                ]),
                state: GENERATOR_DISK,
                initial: {
                    wordCapitalize: false,
                    wordIncludeNumber: false,
                    website: null,
                },
                options: {
                    deserializer: (value) => value,
                    clearOn: ["logout"],
                },
            },
            constraints: {
                default: {},
                create(_policies, _context) {
                    return new identity_state_constraint_IdentityConstraint();
                },
            },
        },
    },
});
/* harmony default export */ const username_eff_word_list = (effWordList);

;// ../../libs/tools/generator/core/src/engine/forwarder.ts
var forwarder_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};




/** Generation algorithms that query an email forwarding service to
 *  create anonymized email addresses.
 */
class forwarder_Forwarder {
    /** Instantiates the email forwarder engine
     *  @param configuration The forwarder to query
     *  @param client requests data from the forwarding service
     *  @param i18nService localizes messages sent to the forwarding service
     *   and user-addressable errors
     */
    constructor(configuration, client, i18nService) {
        this.configuration = configuration;
        this.client = client;
        this.i18nService = i18nService;
    }
    generate(request, settings) {
        return forwarder_awaiter(this, void 0, void 0, function* () {
            const requestOptions = { website: request.website };
            const getAccount = yield this.getAccountId(this.configuration, settings);
            if (getAccount) {
                requestOptions.accountId = yield this.client.fetchJson(getAccount, requestOptions);
            }
            const create = this.createForwardingAddress(this.configuration, settings);
            const result = yield this.client.fetchJson(create, requestOptions);
            return new GeneratedCredential(result, Type.email, Date.now());
        });
    }
    createContext(configuration, settings) {
        return new ForwarderContext(configuration, settings, this.i18nService);
    }
    createForwardingAddress(configuration, settings) {
        const context = this.createContext(configuration, settings);
        const rpc = new CreateForwardingAddressRpc(configuration, context);
        return rpc;
    }
    getAccountId(configuration, settings) {
        if (!configuration.forwarder.getAccountId) {
            return null;
        }
        const context = this.createContext(configuration, settings);
        const rpc = new GetAccountIdRpc(configuration, context);
        return rpc;
    }
}

;// ../../libs/tools/generator/core/src/metadata/email/forwarder.ts




// update the extension metadata
function forwarder_toForwarderMetadata(extension) {
    var _a;
    if (extension.site.id !== "forwarder") {
        throw new Error(`expected forwarder extension; received ${extension.site.id} (${extension.product.vendor.id})`);
    }
    const name = { literal: (_a = extension.product.name) !== null && _a !== void 0 ? _a : extension.product.vendor.name };
    const generator = {
        id: { forwarder: extension.product.vendor.id },
        type: Type.email,
        weight: 300,
        i18nKeys: {
            name,
            description: "forwardedEmailDesc",
            generateCredential: "generateEmail",
            credentialGenerated: "emailGenerated",
            useCredential: "useThisEmail",
            credentialType: "email",
            copyCredential: "copyEmail",
        },
        capabilities: {
            autogenerate: false,
            fields: [...extension.requestedFields],
        },
        engine: {
            create(dependencies) {
                const config = getForwarderConfiguration(extension.product.vendor.id);
                return new Forwarder(config, dependencies.client, dependencies.i18nService);
            },
        },
        profiles: {
            [Profile.account]: {
                type: "extension",
                site: "forwarder",
                storage: {
                    key: "forwarder",
                    frame: 512,
                    initial: {
                        token: "",
                        baseUrl: "",
                        domain: "",
                        prefix: "",
                    },
                    options: {
                        deserializer: (value) => value,
                        clearOn: ["logout"],
                    },
                },
                constraints: {
                    default: {},
                    create() {
                        return new IdentityConstraint();
                    },
                },
            },
        },
    };
    return generator;
}

;// ../../libs/tools/generator/core/src/metadata/util.ts

/** Returns true when the input algorithm is a password algorithm. */
function isPasswordAlgorithm(algorithm) {
    return AlgorithmsByType.password.includes(algorithm);
}
/** Returns true when the input algorithm is a username algorithm. */
function isUsernameAlgorithm(algorithm) {
    return AlgorithmsByType.username.includes(algorithm);
}
/** Returns true when the input algorithm is a forwarder integration. */
function util_isForwarderExtensionId(algorithm) {
    return !!(algorithm && typeof algorithm === "object" && "forwarder" in algorithm);
}
/** Extract a `VendorId` from a `CredentialAlgorithm`.
 *  @param algorithm the algorithm containing the vendor id
 *  @returns the vendor id if the algorithm identifies a forwarder extension.
 *   Otherwise, undefined.
 */
function util_toVendorId(algorithm) {
    if (util_isForwarderExtensionId(algorithm)) {
        return algorithm.forwarder;
    }
}
/** Returns true when the input algorithm is an email algorithm. */
function isEmailAlgorithm(algorithm) {
    return AlgorithmsByType.email.includes(algorithm) || util_isForwarderExtensionId(algorithm);
}
/** Returns true when the algorithms are the same. */
function isSameAlgorithm(lhs, rhs) {
    if (lhs === rhs) {
        return true;
    }
    else if (util_isForwarderExtensionId(lhs) && util_isForwarderExtensionId(rhs)) {
        return lhs.forwarder === rhs.forwarder;
    }
    else {
        return false;
    }
}
/** Returns true when the input describes a core profile. */
function isCoreProfile(value) {
    return value.type === "core";
}
/** Returns true when the input describes a forwarder extension profile. */
function util_isForwarderProfile(value) {
    return value.type === "extension" && value.site === "forwarder";
}

;// ../../libs/tools/generator/core/src/metadata/index.ts






/** Credential generators hosted natively by the credential generator system.
 *  These are supplemented by generators from the {@link ExtensionService}.
 */
const metadata_BuiltIn = Object.freeze({
    /** Catchall email address generator */
    catchall: email_catchall,
    /** plus-addressed email address generator */
    plusAddress: plus_address,
    /** passphrase generator using the EFF word list */
    passphrase: eff_word_list,
    /** password generator */
    password: random_password,
    /** username generator using the EFF word list */
    effWordList: username_eff_word_list,
});
// `CredentialAlgorithm` is defined in terms of `ABT`; supplying
// type information in the barrel file breaks a circular dependency.
/** Credential generation algorithms grouped by purpose. */
const metadata_AlgorithmsByType = data_AlgorithmsByType;
/** A list of all built-in algorithm identifiers
 *  @remarks this is useful when you need to filter invalid values
 */
const metadata_Algorithms = Object.freeze(Object.values(Algorithm));
/** A list of all built-in algorithm types
 *  @remarks this is useful when you need to filter invalid values
 */
const metadata_Types = Object.freeze(Object.values(data_Type));




;// ../../libs/common/src/tools/rx.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

/** Returns its input. */
function identity(value) {
    return value;
}
/** Combines its arguments into a plain old javascript object. */
function expectedAndActualValue(expectedValue, actualValue) {
    return {
        expectedValue,
        actualValue,
    };
}
/**
 * An observable operator that throws an error when the stream's
 *   value changes. Uses strict (`===`) comparison checks.
 * @param extract a function that identifies the member to compare;
 *   defaults to the identity function
 * @param error a function that packages the expected and failed
 *   values into an error.
 * @returns a stream of values that emits when the input emits,
 *   completes when the input completes, and errors when either the
 *   input errors or the comparison fails.
 */
function errorOnChange(extract = identity, error = expectedAndActualValue) {
    return (0,external_rxjs_namespaceObject.pipe)((0,external_rxjs_namespaceObject.startWith)(null), (0,external_rxjs_namespaceObject.pairwise)(), (0,external_rxjs_namespaceObject.map)(([expected, actual], i) => {
        // always let the first value through
        if (i === 0) {
            return actual;
        }
        const expectedValue = extract(expected);
        const actualValue = extract(actual);
        // fail the stream if the state desyncs from its initial value
        if (expectedValue === actualValue) {
            return actual;
        }
        else {
            throw error(expectedValue, actualValue);
        }
    }));
}
/**
 * An observable operator that reduces an emitted collection to a single object,
 * returning a default if all items are ignored.
 * @param reduce The reduce function to apply to the filtered collection. The
 *  first argument is the accumulator, and the second is the current item. The
 *  return value is the new accumulator.
 * @param defaultValue The default value to return if the collection is empty. The
 *   default value is also the initial value of the accumulator.
 */
function reduceCollection(reduce, defaultValue) {
    return (0,external_rxjs_namespaceObject.map)((values) => {
        const reduced = (values !== null && values !== void 0 ? values : []).reduce(reduce, structuredClone(defaultValue));
        return reduced;
    });
}
/**
 * An observable operator that emits distinct values by checking that all
 *   values in the previous entry match the next entry. This method emits
 *   when a key is added and does not when a key is removed.
 * @remarks This method checks objects. It does not check items in arrays.
 */
function distinctIfShallowMatch() {
    return (0,external_rxjs_namespaceObject.distinctUntilChanged)((previous, current) => {
        let isDistinct = true;
        for (const key in current) {
            isDistinct && (isDistinct = previous[key] === current[key]);
        }
        return isDistinct;
    });
}
/** Create an observable that, once subscribed, emits `true` then completes when
 *   any input completes. If an input is already complete when the subscription
 *   occurs, it emits immediately.
 *  @param watch$ the observable(s) to watch for completion; if an array is passed,
 *   null and undefined members are ignored. If `watch$` is empty, `anyComplete`
 *   will never complete.
 *  @returns An observable that emits `true` when any of its inputs
 *   complete. The observable forwards the first error from its input.
 *  @remarks This method is particularly useful in combination with `takeUntil` and
 *   streams that are not guaranteed to complete on their own.
 */
function rx_anyComplete(watch$) {
    if (Array.isArray(watch$)) {
        const completes$ = watch$
            .filter((w$) => !!w$)
            .map((w$) => w$.pipe((0,external_rxjs_namespaceObject.ignoreElements)(), (0,external_rxjs_namespaceObject.endWith)(true)));
        const completed$ = (0,external_rxjs_namespaceObject.race)(completes$);
        return completed$;
    }
    else {
        return watch$.pipe((0,external_rxjs_namespaceObject.ignoreElements)(), (0,external_rxjs_namespaceObject.endWith)(true));
    }
}
/**
 * Create an observable that delays the input stream until all watches have
 *  emitted a value. The watched values are not included in the source stream.
 *  The last emission from the source is output when all the watches have
 *  emitted at least once.
 * @param watch$ the observable(s) to watch for readiness. If `watch$` is empty,
 *  `ready` will never emit.
 * @returns An observable that emits when the source stream emits. The observable
 *   errors if one of its watches completes before emitting. It also errors if one
 *   of its watches errors.
 */
function ready(watch$) {
    const watching$ = Array.isArray(watch$) ? watch$ : [watch$];
    return (0,external_rxjs_namespaceObject.pipe)((0,external_rxjs_namespaceObject.connect)((source$) => {
        // this subscription is safe because `source$` connects only after there
        // is an external subscriber.
        const source = new external_rxjs_namespaceObject.ReplaySubject(1);
        source$.subscribe(source);
        // `concat` is subscribed immediately after it's returned, at which point
        // `zip` blocks until all items in `watching$` are ready. If that occurs
        // after `source$` is hot, then the replay subject sends the last-captured
        // emission through immediately. Otherwise, `ready` waits for the next
        // emission
        return (0,external_rxjs_namespaceObject.concat)((0,external_rxjs_namespaceObject.zip)(watching$).pipe((0,external_rxjs_namespaceObject.first)(), (0,external_rxjs_namespaceObject.ignoreElements)()), source).pipe((0,external_rxjs_namespaceObject.takeUntil)(rx_anyComplete(source)));
    }));
}
function withLatestReady(...watches$) {
    return (0,external_rxjs_namespaceObject.connect)((source$) => {
        // these subscriptions are safe because `source$` connects only after there
        // is an external subscriber.
        const source = new external_rxjs_namespaceObject.ReplaySubject(1);
        source$.subscribe(source);
        const watches = watches$.map((w) => {
            const watch$ = new external_rxjs_namespaceObject.ReplaySubject(1);
            w.subscribe(watch$);
            return watch$;
        });
        // `concat` is subscribed immediately after it's returned, at which point
        // `zip` blocks until all items in `watches` are ready. If that occurs
        // after `source$` is hot, then the replay subject sends the last-captured
        // emission through immediately. Otherwise, `withLatestFrom` waits for the
        // next emission
        return (0,external_rxjs_namespaceObject.concat)((0,external_rxjs_namespaceObject.zip)(watches).pipe((0,external_rxjs_namespaceObject.first)(), (0,external_rxjs_namespaceObject.ignoreElements)()), source).pipe((0,external_rxjs_namespaceObject.withLatestFrom)(...watches), (0,external_rxjs_namespaceObject.takeUntil)(rx_anyComplete(source)));
    });
}
/**
 * Create an observable that emits the latest value of the source stream
 *  when `watch$` emits. If `watch$` emits before the stream emits, then
 *  an emission occurs as soon as a value becomes ready.
 * @param watch$ the observable that triggers emissions
 * @returns An observable that emits when `watch$` emits. The observable
 *  errors if its source stream errors. It also errors if `on` errors. It
 *  completes if its watch completes.
 *
 * @remarks This works like `audit`, but it repeats emissions when
 *  watch$ fires.
 */
function on(watch$) {
    return pipe(connect((source$) => {
        const source = new ReplaySubject(1);
        source$.subscribe(source);
        return watch$
            .pipe(ready(source), concatMap(() => source.pipe(first())))
            .pipe(takeUntil(rx_anyComplete(source)));
    }));
}
/** Create an observable that emits the first value from the source and
 *  throws if the observable emits another value.
 *  @param options.name names the pin to make discovering failing observables easier
 *  @param options.distinct compares two emissions with each other to determine whether
 *   the second emission is a duplicate. When this is specified, duplicates are ignored.
 *   When this isn't specified, any emission after the first causes the pin to throw
 *   an error.
 */
function rx_pin(options) {
    return (0,external_rxjs_namespaceObject.pipe)((options === null || options === void 0 ? void 0 : options.distinct) ? (0,external_rxjs_namespaceObject.distinctUntilChanged)(options.distinct) : (i) => i, (0,external_rxjs_namespaceObject.map)((value, index) => {
        var _a, _b;
        if (index > 0) {
            throw new Error(`${(_b = (_a = options === null || options === void 0 ? void 0 : options.name) === null || _a === void 0 ? void 0 : _a.call(options)) !== null && _b !== void 0 ? _b : "unknown"} observable should only emit one value.`);
        }
        else {
            return value;
        }
    }));
}
/** maps a value to a result and keeps a cache of the mapping
 *  @param mapResult - maps the stream to a result; this function must return
 *    a value. It must not return null or undefined.
 *  @param options.size - the number of entries in the cache
 *  @param options.key - maps the source to a cache key
 *  @remarks this method is useful for optimization of expensive
 *    `mapResult` calls. It's also useful when an interned reference type
 *    is needed.
 */
function rx_memoizedMap(mapResult, options) {
    return pipe(
    // scan's accumulator contains the cache
    scan(([cache], source) => {
        var _a, _b, _c, _d;
        const key = (_b = (_a = options === null || options === void 0 ? void 0 : options.key) === null || _a === void 0 ? void 0 : _a.call(options, source)) !== null && _b !== void 0 ? _b : source;
        // cache hit?
        let result = cache === null || cache === void 0 ? void 0 : cache.get(key);
        if (result) {
            return [cache, result];
        }
        // cache miss
        result = mapResult(source);
        cache === null || cache === void 0 ? void 0 : cache.set(key, result);
        // trim cache
        const overage = cache.size - ((_c = options === null || options === void 0 ? void 0 : options.size) !== null && _c !== void 0 ? _c : 1);
        if (overage > 0) {
            Array.from((_d = cache === null || cache === void 0 ? void 0 : cache.keys()) !== null && _d !== void 0 ? _d : [])
                .slice(0, overage)
                .forEach((k) => cache === null || cache === void 0 ? void 0 : cache.delete(k));
        }
        return [cache, result];
    }, 
    // FIXME: upgrade to a least-recently-used cache
    [new Map(), null]), 
    // encapsulate cache
    map(([, result]) => result), 
    // preserve `NonNullable` constraint on `Result`
    filter((result) => !!result));
}

;// ../../libs/common/src/tools/state/classified-format.ts
function isClassifiedFormat(value) {
    return (!!value &&
        "id" in value &&
        "secret" in value &&
        "disclosed" in value &&
        typeof value.secret === "string" &&
        typeof value.disclosed === "object");
}

;// ../../libs/common/src/tools/state/object-key.ts

/** Performs a type inference that identifies object keys. */
function isObjectKey(key) {
    return key.target === "object" && "format" in key && "classifier" in key;
}
/** Converts an object key to a plaform-compatible `UserKeyDefinition`. */
function toUserKeyDefinition(key) {
    if (key.format === "plain") {
        const plain = new UserKeyDefinition(key.state, key.key, key.options);
        return plain;
    }
    else if (key.format === "classified") {
        const classified = new UserKeyDefinition(key.state, key.key, {
            cleanupDelayMs: key.options.cleanupDelayMs,
            deserializer: (jsonValue) => jsonValue,
            clearOn: key.options.clearOn,
        });
        return classified;
    }
    else if (key.format === "secret-state") {
        const classified = new UserKeyDefinition(key.state, key.key, {
            cleanupDelayMs: key.options.cleanupDelayMs,
            deserializer: (jsonValue) => jsonValue,
            clearOn: key.options.clearOn,
        });
        return classified;
    }
    else {
        throw new Error(`unknown format: ${key.format}`);
    }
}

;// ../../libs/common/src/tools/state/state-constraints-dependency.ts
/** Returns `true` if the input constraint is a `DynamicStateConstraints<T>`.
 *  Otherwise, returns false.
 *  @param constraints the constraint to evaluate.
 * */
function isDynamic(constraints) {
    return constraints && "calibrate" in constraints;
}

;// ../../libs/common/src/tools/state/user-state-subject.ts
var user_state_subject_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore







// FIXME: The subject should always repeat the value when it's own `next` method is called.
//
// Chrome StateService only calls `next` when the underlying values changes. When enforcing,
// say, a minimum constraint, any value beneath the minimum becomes the minimum. This prevents
// invalid data received in sequence from calling `next` because the state provider doesn't
// emit.
//
// The hack is pretty simple. Insert arbitrary data into the saved data to ensure
// that it *always* changes.
//
// Any real fix will be fairly complex because it needs to recognize *fast* when it
// is waiting. Alternatively, the kludge could become a format properly fed by random noise.
//
// NOTE: this only matters for plaintext objects; encrypted fields change with every
//   update b/c their IVs change.
const ALWAYS_UPDATE_KLUDGE = "$^$ALWAYS_UPDATE_KLUDGE_PROPERTY$^$";
/** Default frame size for data packing */
const DEFAULT_FRAME_SIZE = 32;
/**
 * Adapt a state provider to an rxjs subject.
 *
 * This subject buffers the last value it received in memory. The buffer is erased
 * if the subject receives a complete or error event. It does not persist the buffer.
 *
 * Warning! The user state subject has a synchronous interface, but subscriptions are
 * always asynchronous.
 *
 * @template State the state stored by the subject
 * @template Dependencies use-specific dependencies provided by the user.
 */
class user_state_subject_UserStateSubject extends external_rxjs_namespaceObject.Observable {
    /**
     * Instantiates the user state subject bound to a persistent backing store
     * @param key identifies the persistent backing store
     * @param getState creates a persistent backing store using a key
     * @param context tailor the subject's behavior for a particular
     *   purpose.
     * @param dependencies.when$ blocks updates to the state subject until
     *   this becomes true. When this occurs, only the last-received update
     *   is applied. The blocked update is kept in memory. It does not persist
     *   to disk.
     * @param dependencies.account$ writes block until the account$
     *   is available.
     */
    constructor(key, providers, context) {
        var _a, _b, _c;
        super();
        this.key = key;
        this.providers = providers;
        this.context = context;
        // using subjects to ensure the right semantics are followed;
        // if greater efficiency becomes desirable, consider implementing
        // `SubjectLike` directly
        this.input = new external_rxjs_namespaceObject.ReplaySubject(1);
        this.output = new external_rxjs_namespaceObject.ReplaySubject(1);
        this.counter = 0;
        if (isObjectKey(this.key)) {
            // classification and encryption only supported with `ObjectKey`
            this.objectKey = this.key;
            this.stateKey = toUserKeyDefinition(this.key);
        }
        else {
            // raw state access granted with `UserKeyDefinition`
            this.objectKey = null;
            this.stateKey = this.key;
        }
        this.log = this.providers.log({
            contextId: this.contextId,
            type: "UserStateSubject",
            storage: {
                state: this.stateKey.stateDefinition.name,
                key: this.stateKey.key,
            },
        });
        // normalize dependencies
        const when$ = ((_a = this.context.when$) !== null && _a !== void 0 ? _a : new external_rxjs_namespaceObject.BehaviorSubject(true)).pipe((0,external_rxjs_namespaceObject.distinctUntilChanged)());
        const account$ = context.account$.pipe(rx_pin({
            name: () => `${this.contextId} { account$ }`,
            distinct(prev, current) {
                return prev.id === current.id;
            },
        }), (0,external_rxjs_namespaceObject.shareReplay)({ refCount: true, bufferSize: 1 }));
        const encryptor$ = this.encryptor(account$);
        const constraints$ = ((_b = this.context.constraints$) !== null && _b !== void 0 ? _b : unconstrained$()).pipe((0,external_rxjs_namespaceObject.catchError)((e) => {
            this.log.error(e, "constraints$ dependency failed; using last-known constraints");
            return external_rxjs_namespaceObject.EMPTY;
        }), (0,external_rxjs_namespaceObject.shareReplay)({ refCount: true, bufferSize: 1 }));
        const dependencies$ = ((_c = this.context.dependencies$) !== null && _c !== void 0 ? _c : new external_rxjs_namespaceObject.BehaviorSubject(null)).pipe((0,external_rxjs_namespaceObject.shareReplay)({ refCount: true, bufferSize: 1 }));
        // load state once the account becomes available
        const userState$ = account$.pipe((0,external_rxjs_namespaceObject.tap)((account) => this.log.debug({ accountId: account.id }, "loading user state")), (0,external_rxjs_namespaceObject.map)((account) => this.providers.state.getUser(account.id, this.stateKey)), (0,external_rxjs_namespaceObject.shareReplay)({ refCount: true, bufferSize: 1 }));
        // wire output before input so that output normalizes the current state
        // before any `next` value is processed
        this.outputSubscription = userState$
            .pipe((0,external_rxjs_namespaceObject.switchMap)((userState) => userState.state$), (0,external_rxjs_namespaceObject.map)((stored) => {
            if (stored && typeof stored === "object" && ALWAYS_UPDATE_KLUDGE in stored) {
                // related: ALWAYS_UPDATE_KLUDGE FIXME
                delete stored[ALWAYS_UPDATE_KLUDGE];
            }
            return stored;
        }), this.declassify(encryptor$), this.adjust((0,external_rxjs_namespaceObject.combineLatestWith)(constraints$)), (0,external_rxjs_namespaceObject.takeUntil)(rx_anyComplete(account$)))
            .subscribe(this.output);
        const last$ = new external_rxjs_namespaceObject.ReplaySubject(1);
        this.output
            .pipe((0,external_rxjs_namespaceObject.last)(), (0,external_rxjs_namespaceObject.map)((o) => o.state))
            .subscribe(last$);
        // the update stream simulates the stateProvider's "shouldUpdate"
        // functionality & applies policy
        const updates$ = (0,external_rxjs_namespaceObject.concat)(this.input.pipe(this.when(when$), this.adjust(withLatestReady(constraints$)), this.prepareUpdate(this, dependencies$)), 
        // when the output subscription completes, its last-emitted value
        // loops around to the input for finalization
        last$.pipe(this.fix(constraints$), this.prepareUpdate(last$, dependencies$)));
        // classification/encryption bound to the input subscription's lifetime
        // to ensure that `fix` has access to the encryptor key
        //
        // FIXME: this should probably timeout when a lock occurs
        this.inputSubscription = updates$
            .pipe(this.classify(encryptor$), (0,external_rxjs_namespaceObject.withLatestFrom)(userState$), (0,external_rxjs_namespaceObject.takeUntil)(rx_anyComplete([when$, this.input, encryptor$])))
            .subscribe({
            next: ([input, state]) => this.onNext(input, state),
            error: (e) => this.onError(e),
            complete: () => this.onComplete(),
        });
    }
    get contextId() {
        return `UserStateSubject(${this.stateKey.stateDefinition.name}, ${this.stateKey.key})`;
    }
    encryptor(account$) {
        var _a, _b;
        const singleUserId$ = account$.pipe((0,external_rxjs_namespaceObject.map)((account) => account.id));
        const frameSize = (_b = (_a = this.objectKey) === null || _a === void 0 ? void 0 : _a.frame) !== null && _b !== void 0 ? _b : DEFAULT_FRAME_SIZE;
        const encryptor$ = this.providers.encryptor.userEncryptor$(frameSize, { singleUserId$ }).pipe((0,external_rxjs_namespaceObject.tap)(() => this.log.debug("encryptor constructed")), (0,external_rxjs_namespaceObject.map)(({ encryptor }) => encryptor), (0,external_rxjs_namespaceObject.shareReplay)({ refCount: true, bufferSize: 1 }));
        return encryptor$;
    }
    when(when$) {
        return (0,external_rxjs_namespaceObject.pipe)((0,external_rxjs_namespaceObject.combineLatestWith)(when$.pipe((0,external_rxjs_namespaceObject.distinctUntilChanged)())), (0,external_rxjs_namespaceObject.tap)(([_, when]) => this.log.debug({ when }, "when status")), (0,external_rxjs_namespaceObject.filter)(([_, when]) => !!when), (0,external_rxjs_namespaceObject.map)(([input]) => input));
    }
    prepareUpdate(init$, dependencies$) {
        return (input$) => (0,external_rxjs_namespaceObject.concat)(
        // `init$` becomes the accumulator for `scan`
        init$.pipe((0,external_rxjs_namespaceObject.first)(), (0,external_rxjs_namespaceObject.map)((init) => [init, null])), input$.pipe((0,external_rxjs_namespaceObject.map)((constrained) => constrained.state), (0,external_rxjs_namespaceObject.withLatestFrom)(dependencies$))).pipe(
        // scan only emits values that can cause updates
        (0,external_rxjs_namespaceObject.scan)(([prev], [pending, dependencies]) => {
            var _a, _b, _c, _d, _e, _f;
            const shouldUpdate = (_c = (_b = (_a = this.context).shouldUpdate) === null || _b === void 0 ? void 0 : _b.call(_a, prev, pending, dependencies)) !== null && _c !== void 0 ? _c : true;
            if (shouldUpdate) {
                // actual update
                const next = (_f = (_e = (_d = this.context).nextValue) === null || _e === void 0 ? void 0 : _e.call(_d, prev, pending, dependencies)) !== null && _f !== void 0 ? _f : pending;
                return [next, dependencies];
            }
            else {
                // false update
                this.log.debug("shouldUpdate prevented write");
                return [prev, null];
            }
        }), 
        // the first emission primes `scan`s aggregator
        (0,external_rxjs_namespaceObject.skip)(1), (0,external_rxjs_namespaceObject.map)(([state]) => state), 
        // clean up false updates
        (0,external_rxjs_namespaceObject.distinctUntilChanged)());
    }
    adjust(withConstraints) {
        return (0,external_rxjs_namespaceObject.pipe)(
        // how constraints are blended with incoming emissions varies:
        // * `output` needs to emit when constraints update
        // * `input` needs to wait until a message flows through the pipe
        withConstraints, (0,external_rxjs_namespaceObject.map)(([loadedState, constraints]) => {
            var _a;
            if (!loadedState && !((_a = this.objectKey) === null || _a === void 0 ? void 0 : _a.initial)) {
                this.log.debug("no value; bypassing adjustment");
                return {
                    constraints: {},
                    state: null,
                };
            }
            this.log.debug("adjusting");
            const unconstrained = loadedState !== null && loadedState !== void 0 ? loadedState : structuredClone(this.objectKey.initial);
            const calibration = isDynamic(constraints)
                ? constraints.calibrate(unconstrained)
                : constraints;
            const adjusted = calibration.adjust(unconstrained);
            this.log.debug("adjusted");
            return {
                constraints: calibration.constraints,
                state: adjusted,
            };
        }));
    }
    fix(constraints$) {
        return (0,external_rxjs_namespaceObject.pipe)((0,external_rxjs_namespaceObject.combineLatestWith)(constraints$), (0,external_rxjs_namespaceObject.map)(([loadedState, constraints]) => {
            this.log.debug("fixing");
            const calibration = isDynamic(constraints)
                ? constraints.calibrate(loadedState)
                : constraints;
            const fixed = calibration.fix(loadedState);
            this.log.debug("fixed");
            return {
                constraints: calibration.constraints,
                state: fixed,
            };
        }));
    }
    declassify(encryptor$) {
        // short-circuit if they key lacks encryption support
        if (!this.objectKey || this.objectKey.format === "plain") {
            this.log.debug("key uses plain format; bypassing declassification");
            return (input$) => input$;
        }
        // all other keys support encryption; enable encryptor support
        return (0,external_rxjs_namespaceObject.pipe)(this.mapToClassifiedFormat(), (0,external_rxjs_namespaceObject.combineLatestWith)(encryptor$), (0,external_rxjs_namespaceObject.concatMap)((_a) => user_state_subject_awaiter(this, [_a], void 0, function* ([input, encryptor]) {
            // pass through null values
            if (input === null || input === undefined) {
                this.log.debug("no value; bypassing declassification");
                return null;
            }
            this.log.debug("declassifying");
            // decrypt classified data
            const { secret, disclosed } = input;
            const encrypted = enc_string_EncString.fromJSON(secret);
            const decryptedSecret = yield encryptor.decrypt(encrypted);
            // assemble into proper state
            const declassified = this.objectKey.classifier.declassify(disclosed, decryptedSecret);
            const state = this.objectKey.options.deserializer(declassified);
            this.log.debug("declassified");
            return state;
        })));
    }
    mapToClassifiedFormat() {
        // FIXME: warn when data is dropped in the console and/or report an error
        //   through the observable; consider redirecting dropped data to a recovery
        //   location
        // user-state subject's default format is object-aware
        if (this.objectKey && this.objectKey.format === "classified") {
            return (0,external_rxjs_namespaceObject.map)((input) => {
                if (!isClassifiedFormat(input)) {
                    this.log.warn("classified data must be in classified format; dropping");
                    return null;
                }
                return input;
            });
        }
        // secret state's format wraps objects in an array
        if (this.objectKey && this.objectKey.format === "secret-state") {
            return (0,external_rxjs_namespaceObject.map)((input) => {
                if (!Array.isArray(input)) {
                    this.log.warn("secret-state requires array formatting; dropping");
                    return null;
                }
                const [unwrapped] = input;
                if (!isClassifiedFormat(unwrapped)) {
                    this.log.warn("unwrapped secret-state must be in classified format; dropping");
                    return null;
                }
                return unwrapped;
            });
        }
        this.log.panic({ format: this.objectKey.format }, "unsupported serialization format");
    }
    classify(encryptor$) {
        // short-circuit if they key lacks encryption support; `encryptor` is
        // readied to preserve `dependencies.singleUserId$` emission contract
        if (!this.objectKey || this.objectKey.format === "plain") {
            this.log.debug("key uses plain format; bypassing classification");
            return (0,external_rxjs_namespaceObject.pipe)(ready(encryptor$), (0,external_rxjs_namespaceObject.map)((input) => input));
        }
        // all other keys support encryption; enable encryptor support
        return (0,external_rxjs_namespaceObject.pipe)(withLatestReady(encryptor$), (0,external_rxjs_namespaceObject.concatMap)((_a) => user_state_subject_awaiter(this, [_a], void 0, function* ([input, encryptor]) {
            // fail fast if there's no value
            if (input === null || input === undefined) {
                this.log.debug("no value; bypassing classification");
                return null;
            }
            this.log.debug("classifying");
            // split data by classification level
            const serialized = JSON.parse(JSON.stringify(input));
            const classified = this.objectKey.classifier.classify(serialized);
            // protect data
            const encrypted = yield encryptor.encrypt(classified.secret);
            const secret = JSON.parse(JSON.stringify(encrypted));
            // wrap result in classified format envelope for storage
            const envelope = {
                id: null,
                secret,
                disclosed: classified.disclosed,
            };
            this.log.debug("classified");
            // deliberate type erasure; the type is restored during `declassify`
            return envelope;
        })), this.mapToStorageFormat());
    }
    mapToStorageFormat() {
        // user-state subject's default format is object-aware
        if (this.objectKey && this.objectKey.format === "classified") {
            return (0,external_rxjs_namespaceObject.map)((input) => input);
        }
        // secret state's format wraps objects in an array
        if (this.objectKey && this.objectKey.format === "secret-state") {
            return (0,external_rxjs_namespaceObject.map)((input) => [input]);
        }
        this.log.panic({ format: this.objectKey.format }, "unsupported serialization format");
    }
    next(value) {
        var _a;
        (_a = this.input) === null || _a === void 0 ? void 0 : _a.next(value);
    }
    error(err) {
        var _a;
        (_a = this.input) === null || _a === void 0 ? void 0 : _a.error(err);
    }
    complete() {
        var _a;
        (_a = this.input) === null || _a === void 0 ? void 0 : _a.complete();
    }
    /** Subscribe to the subject's event stream
     * @param observer listening for events
     * @returns the subscription
     */
    subscribe(observer) {
        return this.output
            .pipe((0,external_rxjs_namespaceObject.map)((wc) => wc.state), (0,external_rxjs_namespaceObject.distinctUntilChanged)())
            .subscribe(observer);
    }
    /** A stream containing settings and their last-applied constraints. */
    get withConstraints$() {
        return this.output.asObservable();
    }
    onNext(value, state) {
        state
            .update(() => {
            this.log.debug("updating");
            if (typeof value === "object") {
                // related: ALWAYS_UPDATE_KLUDGE FIXME
                const counter = this.counter++;
                if (counter > Number.MAX_SAFE_INTEGER) {
                    this.counter = 0;
                }
                const kludge = Object.assign({}, value);
                kludge[ALWAYS_UPDATE_KLUDGE] = counter;
            }
            this.log.debug("updated");
            return value;
        })
            .catch((e) => {
            this.log.error(e, "updating failed");
            this.onError(e);
        });
    }
    onError(value) {
        if (!this.isDisposed) {
            this.log.debug(value, "forwarding error to subscribers");
            this.output.error(value);
        }
        this.dispose();
    }
    onComplete() {
        if (!this.isDisposed) {
            this.output.complete();
        }
        this.dispose();
    }
    get isDisposed() {
        return this.input === null;
    }
    dispose() {
        var _a, _b;
        if (!this.isDisposed) {
            this.log.debug("disposing");
            // clean up internal subscriptions
            (_a = this.inputSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
            (_b = this.outputSubscription) === null || _b === void 0 ? void 0 : _b.unsubscribe();
            this.inputSubscription = null;
            this.outputSubscription = null;
            // drop input to ensure its value is removed from memory
            this.input = null;
            this.log.debug("disposed");
        }
    }
}

;// ../../libs/tools/generator/core/src/providers/credential-preferences.ts


/** plaintext password generation options */
const credential_preferences_PREFERENCES = new UserKeyDefinition(GENERATOR_DISK, "credentialPreferences", {
    deserializer: (value) => {
        var _a;
        const result = (_a = value) !== null && _a !== void 0 ? _a : {};
        for (const key in metadata_AlgorithmsByType) {
            const type = key;
            if (result[type]) {
                result[type].updated = new Date(result[type].updated);
            }
            else {
                const [algorithm] = metadata_AlgorithmsByType[type];
                result[type] = { algorithm, updated: new Date() };
            }
        }
        return result;
    },
    clearOn: ["logout"],
});

;// ../../libs/tools/generator/core/src/providers/generator-metadata-provider.ts








/** Surfaces contextual information to credential generators */
class generator_metadata_provider_GeneratorMetadataProvider {
    /** Instantiates the context provider
     *  @param system dependency providers for user state subjects
     *  @param application dependency providers for system services
     */
    constructor(system, application, algorithms) {
        this.system = system;
        this.application = application;
        this.log = system.log({ type: "GeneratorMetadataProvider" });
        const site = application.extension.site("forwarder");
        if (!site) {
            this.log.panic("forwarder extension site not found");
        }
        this.site = site;
        this._metadata = new Map(algorithms.map((a) => [a.id, a]));
    }
    /** Retrieve an algorithm's generator metadata
     *  @param algorithm identifies the algorithm
     *  @returns the algorithm's generator metadata
     *  @throws when the algorithm doesn't identify a known metadata entry
     */
    metadata(algorithm) {
        let result = null;
        if (isForwarderExtensionId(algorithm)) {
            const extension = this.site.extensions.get(algorithm.forwarder);
            if (!extension) {
                this.log.panic(algorithm, "extension not found");
            }
            result = toForwarderMetadata(extension);
        }
        else {
            result = this._metadata.get(algorithm);
        }
        if (!result) {
            this.log.panic({ algorithm }, "metadata not found");
        }
        return result;
    }
    /** retrieve credential types */
    types() {
        return Types;
    }
    algorithms(requested) {
        let algorithms;
        if (isTypeRequest(requested)) {
            let forwarders = [];
            if (requested.type === Type.email) {
                forwarders = Array.from(this.site.extensions.keys()).map((forwarder) => ({ forwarder }));
            }
            algorithms = AlgorithmsByType[requested.type].concat(forwarders);
        }
        else if (isAlgorithmRequest(requested) && isForwarderExtensionId(requested.algorithm)) {
            algorithms = this.site.extensions.has(requested.algorithm.forwarder)
                ? [requested.algorithm]
                : [];
        }
        else if (isAlgorithmRequest(requested)) {
            algorithms = Algorithms.includes(requested.algorithm) ? [requested.algorithm] : [];
        }
        else {
            this.log.panic(requested, "algorithm or type required");
        }
        return algorithms;
    }
    // emits a function that returns `true` when the input algorithm is available
    isAvailable$(dependencies) {
        const id$ = dependencies.account$.pipe(map((account) => account.id), pin(), shareReplay({ bufferSize: 1, refCount: true }));
        const available$ = id$.pipe(switchMap((id) => {
            const policies$ = this.application.policy
                .policiesByType$(PolicyType.PasswordGenerator, id)
                .pipe(map((p) => availableAlgorithms(p)
                .filter((a) => this._metadata.has(a))
                .sort()), 
            // interning the set transformation lets `distinctUntilChanged()` eliminate
            // repeating policy emissions using reference equality
            memoizedMap((a) => new Set(a), { key: (a) => a.join(":") }), distinctUntilChanged(), 
            // complete policy emissions otherwise `switchMap` holds `available$` open indefinitely
            takeUntil(anyComplete(id$)));
            return policies$;
        }), map((available) => function (a) {
            return isForwarderExtensionId(a) || available.has(a);
        }));
        return available$;
    }
    algorithms$(requested, dependencies) {
        if (isTypeRequest(requested)) {
            const { type } = requested;
            return this.isAvailable$(dependencies).pipe(map((isAvailable) => this.algorithms({ type }).filter(isAvailable)));
        }
        else if (isAlgorithmRequest(requested)) {
            const { algorithm } = requested;
            return this.isAvailable$(dependencies).pipe(map((isAvailable) => (isAvailable(algorithm) ? [algorithm] : [])));
        }
        else {
            this.log.panic(requested, "algorithm or type required");
        }
    }
    preference$(type, dependencies) {
        const account$ = dependencies.account$.pipe(shareReplay({ bufferSize: 1, refCount: true }));
        const algorithm$ = this.preferences({ account$ }).pipe(map((preferences) => preferences[type].algorithm), distinctUntilChanged());
        return algorithm$;
    }
    /** Get a subject bound to credential generator preferences.
     *  @param dependencies.account$ identifies the account to which the preferences are bound
     *  @returns a subject bound to the user's preferences
     *  @remarks Preferences determine which algorithms are used when generating a
     *   credential from a credential type (e.g. `PassX` or `Username`). Preferences
     *   should not be used to hold navigation history. Use @bitwarden/generator-navigation
     *   instead.
     */
    preferences(dependencies) {
        const account$ = dependencies.account$.pipe(shareReplay({ bufferSize: 1, refCount: true }));
        const constraints$ = this.isAvailable$({ account$ }).pipe(map((isAvailable) => new AvailableAlgorithmsConstraint(this.algorithms.bind(this), isAvailable, this.system)));
        const subject = new UserStateSubject(PREFERENCES, this.system, { account$, constraints$ });
        return subject;
    }
}

;// ../../libs/tools/generator/core/src/providers/generator-profile-provider.ts




/** Surfaces contextual information to credential generators */
class generator_profile_provider_GeneratorProfileProvider {
    /** Instantiates the context provider
     *  @param providers dependency injectors for user state subjects
     *  @param policyService settings constraint lookups
     */
    constructor(providers, policyService) {
        this.providers = providers;
        this.policyService = policyService;
        this.log = providers.log({ type: "GeneratorProfileProvider" });
    }
    /** Get a subject bound to a specific user's settings for the provided profile.
     * @param profile determines which profile's settings are loaded
     * @param dependencies.singleUserId$ identifies the user to which the settings are bound
     * @returns an observable that emits the subject once `dependencies.singleUserId$` becomes
     *   available and then completes.
     * @remarks the subject tracks and enforces policy on the settings it contains.
     *   It completes when `dependencies.singleUserId$` competes or the user's encryption key
     *   becomes unavailable.
     */
    settings(profile, dependencies) {
        const account$ = dependencies.account$.pipe(shareReplay({ bufferSize: 1, refCount: true }));
        const constraints$ = this.constraints$(profile, { account$ });
        const subject = new UserStateSubject(profile.storage, this.providers, {
            constraints$,
            account$,
        });
        return subject;
    }
    /** Get the policy constraints for the provided profile
     *  @param dependencies.account$ constraints are loaded from this account.
     *    If the account's email is verified, it is passed to the constraints
     *  @returns an observable that emits the policy once `dependencies.userId$`
     *   and the policy become available.
     */
    constraints$(profile, dependencies) {
        const account$ = dependencies.account$.pipe(shareReplay({ bufferSize: 1, refCount: true }));
        const constraints$ = account$.pipe(distinctUntilChanged((prev, next) => {
            return prev.email === next.email && prev.emailVerified === next.emailVerified;
        }), switchMap((account) => {
            var _a;
            this.log.debug({
                accountId: account.id,
                profileType: profile.type,
                policyType: (_a = profile.constraints.type) !== null && _a !== void 0 ? _a : "N/A",
                defaultConstraints: profile.constraints.default,
            }, "initializing constraints$");
            const policies$ = profile.constraints.type
                ? this.policyService.policiesByType$(profile.constraints.type, account.id)
                : of([]);
            const context = {
                defaultConstraints: profile.constraints.default,
            };
            if (account.emailVerified) {
                this.log.debug({ email: account.email }, "verified email detected; including in context");
                context.email = account.email;
            }
            const constraints$ = policies$.pipe(map((policies) => profile.constraints.create(policies, context)), distinctUntilChanged((previous, next) => {
                return equivalent(previous, next);
            }), tap((constraints) => this.log.debug(constraints, "constraints updated")));
            return constraints$;
        }), 
        // complete policy emissions otherwise `switchMap` holds `constraints$`
        // open indefinitely
        takeUntil(anyComplete(account$)));
        return constraints$;
    }
}

;// ../../libs/tools/generator/core/src/providers/index.ts



;// ../../libs/tools/generator/core/src/services/default-generator.service.ts
var default_generator_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

/** {@link GeneratorServiceAbstraction} */
class DefaultGeneratorService {
    /** Instantiates the generator service
     * @param strategy tailors the service to a specific generator type
     *            (e.g. password, passphrase)
     * @param policy provides the policy to enforce
     */
    constructor(strategy, policy) {
        this.strategy = strategy;
        this.policy = policy;
        this._evaluators$ = new Map();
    }
    /** {@link GeneratorService.options$} */
    options$(userId) {
        return this.strategy.durableState(userId).state$;
    }
    /** {@link GeneratorService.defaults$} */
    defaults$(userId) {
        return this.strategy.defaults$(userId);
    }
    /** {@link GeneratorService.saveOptions} */
    saveOptions(userId, options) {
        return default_generator_service_awaiter(this, void 0, void 0, function* () {
            yield this.strategy.durableState(userId).update(() => options);
        });
    }
    /** {@link GeneratorService.evaluator$} */
    evaluator$(userId) {
        let evaluator$ = this._evaluators$.get(userId);
        if (!evaluator$) {
            evaluator$ = this.createEvaluator(userId);
            this._evaluators$.set(userId, evaluator$);
        }
        return evaluator$;
    }
    createEvaluator(userId) {
        const evaluator$ = this.policy.policiesByType$(this.strategy.policy, userId).pipe(
        // create the evaluator from the policies
        this.strategy.toEvaluator());
        return evaluator$;
    }
    /** {@link GeneratorService.enforcePolicy} */
    enforcePolicy(userId, options) {
        return default_generator_service_awaiter(this, void 0, void 0, function* () {
            const policy = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.evaluator$(userId));
            const evaluated = policy.applyPolicy(options);
            const sanitized = policy.sanitize(evaluated);
            return sanitized;
        });
    }
    /** {@link GeneratorService.generate} */
    generate(options) {
        return default_generator_service_awaiter(this, void 0, void 0, function* () {
            return yield this.strategy.generate(options);
        });
    }
}

;// ../../libs/tools/generator/core/src/services/default-credential-generator.service.ts




const ALGORITHM_CACHE_SIZE = 10;
const THREE_MINUTES = (/* unused pure expression or super */ null && (3 * 60 * 1000));
class default_credential_generator_service_DefaultCredentialGeneratorService {
    /** Instantiate the `DefaultCredentialGeneratorService`.
     *  @param provide application services required by the credential generator.
     *  @param system low-level services required by the credential generator.
     */
    constructor(provide, system) {
        this.provide = provide;
        this.system = system;
        this.log = system.log({ type: "DefaultCredentialGeneratorService" });
    }
    generate$(dependencies) {
        const request$ = dependencies.on$.pipe(shareReplay({ refCount: true, bufferSize: 1 }));
        const account$ = dependencies.account$.pipe(shareReplay({ refCount: true, bufferSize: 1 }));
        // load algorithm metadata
        const metadata$ = request$.pipe(switchMap((request) => {
            if (isAlgorithmRequest(request)) {
                return of(request.algorithm);
            }
            else if (isTypeRequest(request)) {
                return this.provide.metadata.preference$(request.type, { account$ }).pipe(first());
            }
            else {
                this.log.panic(request, "algorithm or category required");
            }
        }), filter((algorithm) => !!algorithm), memoizedMap((algorithm) => this.provide.metadata.metadata(algorithm), {
            size: ALGORITHM_CACHE_SIZE,
        }), shareReplay({ refCount: true, bufferSize: 1 }));
        // load the active profile's settings
        const settings$ = zip(request$, metadata$).pipe(map(([request, metadata]) => { var _a; return [Object.assign(Object.assign({}, request), { profile: (_a = request.profile) !== null && _a !== void 0 ? _a : Profile.account }), metadata]; }), memoizedMap(([request, metadata]) => {
            const [profile, algorithm] = [request.profile, metadata.id];
            // settings$ stays hot and buffers the most recent value in the cache
            // for the next `request`
            const settings$ = this.settings(metadata, { account$ }, profile).pipe(tap(() => this.log.debug({ algorithm, profile }, "settings update received")), share({
                connector: () => new ReplaySubject(1, THREE_MINUTES),
                resetOnRefCountZero: () => timer(THREE_MINUTES),
            }), tap({
                subscribe: () => this.log.debug({ algorithm, profile }, "settings hot"),
                complete: () => this.log.debug({ algorithm, profile }, "settings cold"),
            }), first());
            this.log.debug({ algorithm, profile }, "settings cached");
            return settings$;
        }, { key: ([request, metadata]) => `${metadata.id}:${request.profile}` }), switchAll());
        // load the algorithm's engine
        const engine$ = metadata$.pipe(memoizedMap((metadata) => {
            const engine = metadata.engine.create(this.provide.generator);
            this.log.debug({ algorithm: metadata.id }, "engine cached");
            return engine;
        }, { size: ALGORITHM_CACHE_SIZE }));
        // generation proper
        const generate$ = zip([request$, settings$, engine$]).pipe(tap(([request]) => this.log.debug(request, "generating credential")), concatMap(([request, settings, engine]) => engine.generate(request, settings)), takeUntil(anyComplete([settings$])));
        return generate$;
    }
    algorithms$(type, dependencies) {
        return this.provide.metadata
            .algorithms$({ type }, dependencies)
            .pipe(map((algorithms) => algorithms.map((a) => this.algorithm(a))));
    }
    preferredAlgorithm$(type, dependencies) {
        const preference$ = this.provide.metadata.preference$(type, dependencies);
        const metadata$ = preference$.pipe(memoizedMap((preference) => this.provide.metadata.metadata(preference)), distinctUntilChanged(), shareReplay({ refCount: true, bufferSize: 1 }));
        return metadata$;
    }
    algorithms(type) {
        const types = Array.isArray(type) ? type : [type];
        const algorithms = types
            .flatMap((type) => this.provide.metadata.algorithms({ type }))
            .map((algorithm) => this.algorithm(algorithm));
        return algorithms;
    }
    algorithm(id) {
        const metadata = this.provide.metadata.metadata(id);
        if (!metadata) {
            this.log.panic({ algorithm: id }, "invalid credential algorithm");
        }
        return metadata;
    }
    forwarder(id) {
        const metadata = this.provide.metadata.metadata({ forwarder: id });
        if (!metadata) {
            this.log.panic({ algorithm: id }, "invalid vendor");
        }
        return metadata;
    }
    preferences(dependencies) {
        return this.provide.metadata.preferences(dependencies);
    }
    settings(metadata, dependencies, profile = Profile.account) {
        const activeProfile = metadata.profiles[profile];
        if (!activeProfile) {
            this.log.panic({ algorithm: metadata.id, profile }, "failed to load settings; profile metadata not found");
        }
        let settings;
        if (isForwarderProfile(activeProfile)) {
            const vendor = toVendorId(metadata.id);
            if (!vendor) {
                this.log.panic({ algorithm: metadata.id, profile }, "failed to load extension profile; vendor not specified");
            }
            this.log.info({ profile, vendor, site: activeProfile.site }, "loading extension profile");
            settings = this.system.extension.settings(activeProfile, vendor, dependencies);
        }
        else {
            this.log.info({ profile, algorithm: metadata.id }, "loading generator profile");
            settings = this.provide.profile.settings(activeProfile, dependencies);
        }
        return settings;
    }
    policy$(metadata, dependencies, profile = Profile.account) {
        const activeProfile = metadata.profiles[profile];
        if (!activeProfile) {
            this.log.panic({ algorithm: metadata.id, profile }, "failed to load policy; profile metadata not found");
        }
        return this.provide.profile.constraints$(activeProfile, dependencies);
    }
}

;// ../../libs/tools/generator/core/src/services/index.ts



;// ../../libs/tools/generator/core/src/factories.ts
// contains logic that constructs generator services dynamically given
// a generator id.
var factories_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};






function createRandomizer() {
    return new PureCryptoRandomizer();
}
/** Instantiates a `CredentialGeneratorService` without Angular DI.
 *  @param system cross-cutting services required by the generator
 *  @param random randomness source
 *  @param encryptor encryption provider
 *  @param state state provider
 *  @param i18n internationalization service
 *  @param api API client
 */
function createCredentialGeneratorService(system, random, encryptor, state, i18n, api) {
    return factories_awaiter(this, void 0, void 0, function* () {
        const userState = {
            encryptor,
            state,
            log: system.log,
            now: Date.now,
        };
        const log = system.log({ type: "createCredentialGeneratorService" });
        const featureFlag = yield system.configService.getFeatureFlag(FeatureFlag.UseSdkPasswordGenerators);
        const sdkService = featureFlag ? system.sdk : undefined;
        log.debug({ featureFlag, sdkAvailable: sdkService !== undefined }, "credential generator service initialized");
        const metadata = new GeneratorMetadataProvider(userState, system, Object.values(BuiltIn));
        const profile = new GeneratorProfileProvider(userState, system.policy);
        const generator = {
            randomizer: random,
            client: new RestClient(api, i18n),
            i18nService: i18n,
            sdk: sdkService,
            now: Date.now,
        };
        const provide = { userState, generator, profile, metadata };
        return new DefaultCredentialGeneratorService(provide, system);
    });
}

;// ../../libs/tools/generator/core/src/integration/index.ts







;// ../../libs/tools/generator/core/src/rx.ts



/** Maps an administrative console policy to a policy evaluator using the provided configuration.
 *  @param configuration the configuration that constructs the evaluator.
 */
function mapPolicyToEvaluator(configuration) {
    return (0,external_rxjs_namespaceObject.pipe)(reduceCollection(configuration.combine, configuration.disabledValue), distinctIfShallowMatch(), (0,external_rxjs_namespaceObject.map)(configuration.createEvaluator));
}
/** Constructs a method that maps a policy to the default (no-op) policy. */
function newDefaultEvaluator() {
    return () => {
        return (0,external_rxjs_namespaceObject.pipe)((0,external_rxjs_namespaceObject.map)((_) => new DefaultPolicyEvaluator()));
    };
}

;// ../../libs/common/src/tools/cryptography/user-encryptor.abstraction.ts
/** An encryption strategy that protects a type's secrets with
 *  user-specific keys. This strategy is bound to a specific user.
 */
class UserEncryptor {
}

;// ../../libs/common/src/tools/cryptography/user-key-encryptor.ts
var user_key_encryptor_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

/** A classification strategy that protects a type's secrets by encrypting them
 *  with a `UserKey`
 */
class UserKeyEncryptor extends UserEncryptor {
    /** Instantiates the encryptor
     *  @param userId identifies the user bound to the encryptor.
     *  @param encryptService protects properties of `Secret`.
     *  @param keyService looks up the user key when protecting data.
     *  @param dataPacker packs and unpacks data classified as secrets.
     */
    constructor(userId, encryptService, key, dataPacker) {
        super();
        this.userId = userId;
        this.encryptService = encryptService;
        this.key = key;
        this.dataPacker = dataPacker;
        this.assertHasValue("userId", userId);
        this.assertHasValue("key", key);
        this.assertHasValue("dataPacker", dataPacker);
        this.assertHasValue("encryptService", encryptService);
    }
    encrypt(secret) {
        return user_key_encryptor_awaiter(this, void 0, void 0, function* () {
            this.assertHasValue("secret", secret);
            let packed = this.dataPacker.pack(secret);
            const encrypted = yield this.encryptService.encryptString(packed, this.key);
            packed = null;
            return encrypted;
        });
    }
    decrypt(secret) {
        return user_key_encryptor_awaiter(this, void 0, void 0, function* () {
            this.assertHasValue("secret", secret);
            let decrypted = yield this.encryptService.decryptString(secret, this.key);
            const unpacked = this.dataPacker.unpack(decrypted);
            decrypted = null;
            return unpacked;
        });
    }
    assertHasValue(name, value) {
        if (value === undefined || value === null) {
            throw new Error(`${name} cannot be null or undefined`);
        }
    }
}

;// ../../libs/common/src/tools/state/buffered-state.ts
var buffered_state_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

/** Stateful storage that overwrites one state with a buffered state.
 *  When a overwrite occurs, the input state is automatically deleted.
 *  @remarks The buffered state can only overwrite non-nullish values. If the
 *   buffer key contains `null` or `undefined`, it will do nothing.
 */
class BufferedState {
    /**
     * Instantiate a buffered state
     * @param provider constructs the buffer.
     * @param key defines the buffer location.
     * @param output updates when a overwrite occurs
     * @param dependency$ provides data the buffer depends upon to evaluate and
     *   transform its data. If this is omitted, then `true` is injected as
     *   a dependency, which with a default output will trigger a overwrite immediately.
     *
     * @remarks `dependency$` enables overwrite control during dynamic circumstances,
     *   such as when a overwrite should occur only if a user key is available.
     */
    constructor(provider, key, output, dependency$ = null) {
        this.key = key;
        this.output = output;
        this.bufferedState = provider.getUser(output.userId, key.toKeyDefinition());
        // overwrite the output value
        const hasValue$ = (0,external_rxjs_namespaceObject.concat)((0,external_rxjs_namespaceObject.of)(null), this.bufferedState.state$).pipe((0,external_rxjs_namespaceObject.map)((buffer) => (buffer !== null && buffer !== void 0 ? buffer : null) !== null));
        const overwriteDependency$ = (dependency$ !== null && dependency$ !== void 0 ? dependency$ : (0,external_rxjs_namespaceObject.of)(true)).pipe((0,external_rxjs_namespaceObject.map)((dependency) => [key.shouldOverwrite(dependency), dependency]));
        const overwrite$ = (0,external_rxjs_namespaceObject.combineLatest)([hasValue$, overwriteDependency$]).pipe((0,external_rxjs_namespaceObject.concatMap)((_a) => buffered_state_awaiter(this, [_a], void 0, function* ([hasValue, [shouldOverwrite, dependency]]) {
            if (hasValue && shouldOverwrite) {
                yield this.overwriteOutput(dependency);
            }
            return [false, null];
        })));
        // drive overwrites only when there's a subscription;
        // the output state determines when emissions occur
        const output$ = this.output.state$.pipe((0,external_rxjs_namespaceObject.map)((output) => [true, output]));
        this.state$ = (0,external_rxjs_namespaceObject.merge)(overwrite$, output$).pipe((0,external_rxjs_namespaceObject.filter)(([emit]) => emit), (0,external_rxjs_namespaceObject.map)(([, output]) => output));
        this.combinedState$ = this.state$.pipe((0,external_rxjs_namespaceObject.map)((state) => [this.output.userId, state]));
        this.bufferedState$ = this.bufferedState.state$;
    }
    overwriteOutput(dependency) {
        return buffered_state_awaiter(this, void 0, void 0, function* () {
            // take the latest value from the buffer
            let buffered;
            yield this.bufferedState.update((state) => {
                buffered = state !== null && state !== void 0 ? state : null;
                return null;
            });
            // update the output state
            const isValid = yield this.key.isValid(buffered, dependency);
            if (isValid) {
                const output = yield this.key.map(buffered, dependency);
                yield this.output.update(() => output);
            }
        });
    }
    /** {@link SingleUserState.userId} */
    get userId() {
        return this.output.userId;
    }
    /** Buffers a value state. The buffered state overwrites the output
     *  state when a subscription occurs.
     *  @param value the state to roll over. Setting this to `null` or `undefined`
     *  has no effect.
     */
    buffer(value) {
        return buffered_state_awaiter(this, void 0, void 0, function* () {
            const normalized = value !== null && value !== void 0 ? value : null;
            if (normalized !== null) {
                yield this.bufferedState.update(() => normalized);
            }
        });
    }
    /** Updates the output state.
     *  @param configureState a callback that returns an updated output
     *   state. The callback receives the state's present value as its
     *   first argument and the dependencies listed in `options.combinedLatestWith`
     *   as its second argument.
     *  @param options configures how the update is applied. See {@link StateUpdateOptions}.
     */
    update(configureState, options = null) {
        return this.output.update(configureState, options);
    }
}

;// ../../libs/common/src/tools/state/data-packer.abstraction.ts
/** A packing strategy that packs data into a string.
 */
class DataPacker {
}

;// ../../libs/common/src/tools/state/padded-data-packer.ts


const DATA_PACKING = Object.freeze({
    /** The character to use for padding. */
    padding: "0",
    /** The character dividing packed data. */
    divider: "|",
    /** A regular expression for detecting invalid padding. When the character
     *  changes, this should be updated to include the new padding pattern.
     */
    hasInvalidPadding: /[^0]/,
});
/** A packing strategy that conceals the length of secret data by padding it
 *  to a multiple of the frame size.
 *  @example
 *  // packed === "24|e2Zvbzp0cnVlfQ==|0000"
 *  const packer = new SecretPacker(24);
 *  const packed = packer.pack({ foo: true });
 */
class PaddedDataPacker extends DataPacker {
    /** Instantiates the padded data packer
     *  @param frameSize The size of the dataframe used to pad encrypted values.
     */
    constructor(frameSize) {
        super();
        this.frameSize = frameSize;
    }
    /**
     * Packs value into a string format that conceals the length by obscuring it
     * with the frameSize.
     * @see {@link DataPackerAbstraction.unpack}
     */
    pack(value) {
        // encode the value
        const json = JSON.stringify(value);
        const b64 = utils_Utils.fromUtf8ToB64(json);
        // calculate packing metadata
        const frameSize = JSON.stringify(this.frameSize);
        const separatorLength = 2 * DATA_PACKING.divider.length; // there are 2 separators
        const payloadLength = b64.length + frameSize.length + separatorLength;
        const paddingLength = this.frameSize - (payloadLength % this.frameSize);
        // pack the data, thereby concealing its length
        const padding = DATA_PACKING.padding.repeat(paddingLength);
        const packed = `${frameSize}|${b64}|${padding}`;
        return packed;
    }
    /** {@link DataPackerAbstraction.unpack} */
    unpack(secret) {
        // frame size is stored before the JSON payload in base 10
        const frameEndIndex = secret.indexOf(DATA_PACKING.divider);
        if (frameEndIndex < 1) {
            throw new Error("missing frame size");
        }
        const frameSize = parseInt(secret.slice(0, frameEndIndex), 10);
        const dataStartIndex = frameEndIndex + 1;
        // The decrypted string should be a multiple of the frame length
        if (secret.length % frameSize > 0) {
            throw new Error("invalid length");
        }
        // encoded data terminates with the divider, followed by the padding character
        const dataEndIndex = secret.lastIndexOf(DATA_PACKING.divider);
        if (dataEndIndex == frameEndIndex) {
            throw new Error("missing json object");
        }
        const paddingStartIndex = dataEndIndex + 1;
        // If the padding contains invalid padding characters then the padding could be used
        // as a side channel for arbitrary data.
        if (secret.slice(paddingStartIndex).match(DATA_PACKING.hasInvalidPadding)) {
            throw new Error("invalid padding");
        }
        // remove frame size and padding
        const b64 = secret.slice(dataStartIndex, dataEndIndex);
        // unpack the stored data
        const json = utils_Utils.fromB64ToUtf8(b64);
        const unpacked = JSON.parse(json);
        return unpacked;
    }
}

;// ../../libs/common/src/tools/state/secret-key-definition.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

/** Encryption and storage settings for data stored by a `SecretState`.
 */
class SecretKeyDefinition {
    constructor(stateDefinition, key, classifier, options, 
    // type erasure is necessary here because typescript doesn't support
    // higher kinded types that generalize over collections. The invariants
    // needed to make this typesafe are maintained by the static factories.
    deconstruct, reconstruct) {
        this.stateDefinition = stateDefinition;
        this.key = key;
        this.classifier = classifier;
        this.options = options;
        this.deconstruct = deconstruct;
        this.reconstruct = reconstruct;
    }
    /** Converts the secret key to the `KeyDefinition` used for secret storage. */
    toEncryptedStateKey() {
        const secretKey = new UserKeyDefinition(this.stateDefinition, this.key, {
            cleanupDelayMs: this.options.cleanupDelayMs,
            deserializer: (jsonValue) => jsonValue,
            // Clear encrypted state on logout
            clearOn: this.options.clearOn,
        });
        return secretKey;
    }
    /**
     * Define a secret state for a single value
     * @param stateDefinition The domain of the secret's durable state.
     * @param key Domain key that identifies the stored value. This key must not be reused
     *    in any capacity.
     * @param classifier Partitions the value into encrypted, discarded, and public data.
     * @param options Configures the operation of the secret state.
     */
    static value(stateDefinition, key, classifier, options) {
        return new SecretKeyDefinition(stateDefinition, key, classifier, options, (value) => [[null, value]], ([[, inner]]) => inner);
    }
    /**
     * Define a secret state for an array of values. Each item is encrypted separately.
     * @param stateDefinition The domain of the secret's durable state.
     * @param key Domain key that identifies the stored items. This key must not be reused
     *    in any capacity.
     * @param classifier Partitions each item into encrypted, discarded, and public data.
     * @param options Configures the operation of the secret state.
     */
    static array(stateDefinition, key, classifier, options) {
        return new SecretKeyDefinition(stateDefinition, key, classifier, options, (value) => value.map((v, id) => [id, v]), (values) => values.map(([, v]) => v));
    }
    /**
     * Define a secret state for a record. Each property is encrypted separately.
     * @param stateDefinition The domain of the secret's durable state.
     * @param key Domain key that identifies the stored properties. This key must not be reused
     *    in any capacity.
     * @param classifier Partitions each property into encrypted, discarded, and public data.
     * @param options Configures the operation of the secret state.
     */
    static record(stateDefinition, key, classifier, options) {
        return new SecretKeyDefinition(stateDefinition, key, classifier, options, (value) => Object.entries(value), (values) => Object.fromEntries(values));
    }
}

;// ../../libs/common/src/tools/state/secret-state.ts
var secret_state_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


const ONE_MINUTE = 1000 * 60;
/** Stores account-specific secrets protected by a UserKeyEncryptor.
 *
 *  @remarks This state store changes the structure of `Plaintext` during
 *  storage, and requires user keys to operate. It is incompatible with sync,
 *  which expects the disk storage format to be identical to the sync format.
 *
 *  DO NOT USE THIS for synchronized data.
 */
class SecretState {
    // The constructor is private to avoid creating a circular dependency when
    // wiring the derived and secret states together.
    constructor(key, $encryptor, userId, provider) {
        this.key = key;
        this.$encryptor = $encryptor;
        // construct the backing store
        this.encryptedState = provider.getUser(userId, key.toEncryptedStateKey());
        // cache plaintext
        this.combinedState$ = (0,external_rxjs_namespaceObject.combineLatest)([this.encryptedState.combinedState$, this.$encryptor]).pipe((0,external_rxjs_namespaceObject.concatMap)((_a) => secret_state_awaiter(this, [_a], void 0, function* ([[userId, state], encryptor]) { return [userId, yield this.declassifyAll(encryptor, state)]; })), (0,external_rxjs_namespaceObject.share)({
            connector: () => {
                return new external_rxjs_namespaceObject.ReplaySubject(1);
            },
            resetOnRefCountZero: () => { var _a; return (0,external_rxjs_namespaceObject.timer)((_a = key.options.cleanupDelayMs) !== null && _a !== void 0 ? _a : ONE_MINUTE); },
        }));
        this.state$ = this.combinedState$.pipe((0,external_rxjs_namespaceObject.map)(([, state]) => state));
    }
    /** {@link SingleUserState.userId} */
    get userId() {
        return this.encryptedState.userId;
    }
    /** Creates a secret state bound to an account encryptor. The account must be unlocked
     *  when this method is called.
     *  @param userId: the user to which the secret state is bound.
     *  @param key Converts between a declassified secret and its formal type.
     *  @param provider constructs state objects.
     *  @param encryptor protects `Secret` data.
     *  @throws when `key.stateDefinition` is backed by memory storage.
     *  @remarks Secrets are written to a secret store as a named tuple. Data classification is
     *    determined by the encryptor's classifier. Secret-classification data is jsonified,
     *    encrypted, and stored in a `secret` property. Disclosed-classification data is stored
     *    in a `disclosed` property. Omitted-classification data is not stored.
     */
    static from(userId, key, provider, encryptor$) {
        const secretState = new SecretState(key, encryptor$, userId, provider);
        return secretState;
    }
    declassifyItem(encryptor_1, _a) {
        return secret_state_awaiter(this, arguments, void 0, function* (encryptor, { id, secret, disclosed }) {
            const encrypted = enc_string_EncString.fromJSON(secret);
            const decrypted = yield encryptor.decrypt(encrypted);
            const declassified = this.key.classifier.declassify(disclosed, decrypted);
            const result = [id, this.key.options.deserializer(declassified)];
            return result;
        });
    }
    declassifyAll(encryptor, data) {
        return secret_state_awaiter(this, void 0, void 0, function* () {
            // fail fast if there's no value
            if (data === null || data === undefined) {
                return null;
            }
            // decrypt each item
            const decryptTasks = data.map((item) => secret_state_awaiter(this, void 0, void 0, function* () { return this.declassifyItem(encryptor, item); }));
            // reconstruct expected type
            const results = yield Promise.all(decryptTasks);
            const result = this.key.reconstruct(results);
            return result;
        });
    }
    classifyItem(encryptor_1, _a) {
        return secret_state_awaiter(this, arguments, void 0, function* (encryptor, [id, item]) {
            const classified = this.key.classifier.classify(item);
            const encrypted = yield encryptor.encrypt(classified.secret);
            // the deserializer in the plaintextState's `derive` configuration always runs, but
            // `encryptedState` is not guaranteed to serialize the data, so it's necessary to
            // round-trip `encrypted` proactively.
            const serialized = {
                id,
                secret: JSON.parse(JSON.stringify(encrypted)),
                disclosed: classified.disclosed,
            };
            return serialized;
        });
    }
    classifyAll(encryptor, data) {
        return secret_state_awaiter(this, void 0, void 0, function* () {
            // fail fast if there's no value
            if (data === null || data === undefined) {
                return null;
            }
            // convert the object to a list format so that all encrypt and decrypt
            // operations are self-similar
            const desconstructed = this.key.deconstruct(data);
            // encrypt each value individually
            const classifyTasks = desconstructed.map((item) => secret_state_awaiter(this, void 0, void 0, function* () { return this.classifyItem(encryptor, item); }));
            const classified = yield Promise.all(classifyTasks);
            return classified;
        });
    }
    /** Updates the secret stored by this state.
     *  @param configureState a callback that returns an updated decrypted
     *   secret state. The callback receives the state's present value as its
     *   first argument and the dependencies listed in `options.combinedLatestWith`
     *   as its second argument.
     *  @param options configures how the update is applied. See {@link StateUpdateOptions}.
     *  @returns a promise that resolves with the updated value read from the state.
     *   The round-trip encrypts, decrypts, and deserializes the data, producing a new
     *   object.
     *  @remarks `configureState` must return a JSON-serializable object.
     *   If there are properties of your class which are not JSON-serializable,
     *   they can be lost when the secret state updates its backing store.
     */
    update(configureState_1) {
        return secret_state_awaiter(this, arguments, void 0, function* (configureState, options = null) {
            var _a, _b, _c;
            const combineLatestWith = (0,external_rxjs_namespaceObject.combineLatest)([
                (_a = options === null || options === void 0 ? void 0 : options.combineLatestWith) !== null && _a !== void 0 ? _a : (0,external_rxjs_namespaceObject.of)(null),
                this.$encryptor,
            ]);
            // read the backing store
            let latestClassified;
            let latestCombined;
            let latestEncryptor;
            yield this.encryptedState.update((c) => c, {
                shouldUpdate: (latest, combined) => {
                    latestClassified = latest;
                    [latestCombined, latestEncryptor] = combined;
                    return false;
                },
                combineLatestWith,
            });
            // exit early if there's no update to apply
            const latestDeclassified = yield this.declassifyAll(latestEncryptor, latestClassified);
            const shouldUpdate = (_c = (_b = options === null || options === void 0 ? void 0 : options.shouldUpdate) === null || _b === void 0 ? void 0 : _b.call(options, latestDeclassified, latestCombined)) !== null && _c !== void 0 ? _c : true;
            if (!shouldUpdate) {
                return latestDeclassified;
            }
            // apply the update
            const updatedDeclassified = configureState(latestDeclassified, latestCombined);
            const updatedClassified = yield this.classifyAll(latestEncryptor, updatedDeclassified);
            yield this.encryptedState.update(() => updatedClassified);
            return updatedDeclassified;
        });
    }
}

;// ../../libs/tools/generator/core/src/abstractions/generator-strategy.abstraction.ts
/** Tailors the generator service to generate a specific kind of credentials */
class GeneratorStrategy {
}

;// ../../libs/tools/generator/core/src/engine/rpc/create-forwarding-address.ts
class create_forwarding_address_CreateForwardingAddressRpc {
    constructor(requestor, context) {
        this.requestor = requestor;
        this.context = context;
    }
    get createForwardingEmail() {
        return this.requestor.forwarder.createForwardingEmail;
    }
    toRequest(req) {
        const url = this.createForwardingEmail.url(req, this.context);
        const token = this.requestor.authenticate(req, this.context);
        const body = this.body(req);
        const request = new Request(url, {
            redirect: "manual",
            cache: "no-store",
            method: "POST",
            headers: new Headers(Object.assign(Object.assign({}, token), { "Content-Type": "application/json", Accept: "application/json" })),
            body,
        });
        return request;
    }
    body(req) {
        const toBody = this.createForwardingEmail.body;
        if (!toBody) {
            return undefined;
        }
        const body = toBody(req, this.context);
        if (!body) {
            return undefined;
        }
        return JSON.stringify(body);
    }
    hasJsonPayload(response) {
        return this.createForwardingEmail.hasJsonPayload(response, this.context);
    }
    processJson(json) {
        return this.createForwardingEmail.processJson(json, this.context);
    }
}

;// ../../libs/tools/generator/core/src/engine/rpc/get-account-id.ts
class get_account_id_GetAccountIdRpc {
    constructor(requestor, context) {
        this.requestor = requestor;
        this.context = context;
    }
    hasJsonPayload(response) {
        return this.requestor.forwarder.getAccountId.hasJsonPayload(response, this.context);
    }
    processJson(json) {
        return this.requestor.forwarder.getAccountId.processJson(json, this.context);
    }
    toRequest(req) {
        const url = this.requestor.forwarder.getAccountId.url(req, this.context);
        const token = this.requestor.authenticate(req, this.context);
        const request = new Request(url, {
            redirect: "manual",
            cache: "no-store",
            method: "GET",
            headers: new Headers(Object.assign(Object.assign({}, token), { "Content-Type": "application/json", Accept: "application/json" })),
        });
        return request;
    }
}

;// ../../libs/tools/generator/core/src/strategies/options-classifier.ts
/** Classifies an object by excluding IntegrationRequest parameters.
 */
class OptionsClassifier {
    /** Partitions `secret` into its disclosed properties and secret properties.
     *  @param value The object to partition
     *  @returns an object that classifies secrets.
     *    The `disclosed` member is new and contains disclosed properties.
     *    The `secret` member is a copy of the secret parameter, including its
     *    prototype, with all disclosed and excluded properties deleted.
     */
    classify(value) {
        const secret = JSON.parse(JSON.stringify(value));
        delete secret.website;
        const disclosed = {};
        return { disclosed, secret };
    }
    /** Merges the properties of `secret` and `disclosed`. When `secret` and
     *  `disclosed` contain the same property, the `secret` property overrides
     *  the `disclosed` property.
     *  @param disclosed an object whose disclosed properties are merged into
     *    the output. Unknown properties are ignored.
     *  @param secret an objects whose properties are merged into the output.
     *    Excluded properties are ignored. Unknown properties are retained.
     *  @returns a new object containing the merged data.
     *
     *  @remarks Declassified data is always jsonified--the purpose of classifying it is
     *   to Jsonify it,
     *   which causes type conversions.
     */
    declassify(_disclosed, secret) {
        const result = Object.assign(Object.assign({}, secret), { website: null });
        return result;
    }
}

;// ../../libs/tools/generator/core/src/strategies/forwarder-generator-strategy.ts
var forwarder_generator_strategy_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore














const OPTIONS_FRAME_SIZE = 512;
/** An email forwarding service configurable through an API. */
class ForwarderGeneratorStrategy extends GeneratorStrategy {
    /** Initializes the generator strategy
     *  @param encryptService protects sensitive forwarder options
     *  @param keyService looks up the user key when protecting data.
     *  @param stateProvider creates the durable state for options storage
     */
    constructor(configuration, client, i18nService, encryptService, keyService, stateProvider) {
        super();
        this.configuration = configuration;
        this.client = client;
        this.i18nService = i18nService;
        this.encryptService = encryptService;
        this.keyService = keyService;
        this.stateProvider = stateProvider;
        // configuration
        this.policy = policy_type_enum_PolicyType.PasswordGenerator;
        this.defaults$ = observe$PerUserId(() => this.configuration.forwarder.defaultSettings);
        this.toEvaluator = newDefaultEvaluator();
        this.durableState = sharedByUserId((userId) => this.getUserSecrets(userId));
        this.generate = (options) => forwarder_generator_strategy_awaiter(this, void 0, void 0, function* () {
            const requestOptions = { website: options.website };
            const getAccount = yield this.getAccountId(this.configuration, options);
            if (getAccount) {
                requestOptions.accountId = yield this.client.fetchJson(getAccount, requestOptions);
            }
            const create = this.createForwardingAddress(this.configuration, options);
            const result = yield this.client.fetchJson(create, requestOptions);
            return result;
        });
    }
    get key() {
        return this.configuration.forwarder.settings;
    }
    get rolloverKey() {
        return this.configuration.forwarder.importBuffer;
    }
    // per-user encrypted state
    getUserSecrets(userId) {
        // construct the encryptor
        const packer = new PaddedDataPacker(OPTIONS_FRAME_SIZE);
        const encryptor$ = this.keyService.userKey$(userId).pipe((0,external_rxjs_namespaceObject.map)((key) => (key ? new UserKeyEncryptor(userId, this.encryptService, key, packer) : null)), (0,external_rxjs_namespaceObject.filter)((encryptor) => !!encryptor));
        // always exclude request properties
        const classifier = new OptionsClassifier();
        // Derive the secret key definition
        const key = SecretKeyDefinition.value(this.key.stateDefinition, this.key.key, classifier, {
            deserializer: (d) => this.key.deserializer(d),
            cleanupDelayMs: this.key.cleanupDelayMs,
            clearOn: this.key.clearOn,
        });
        // the type parameter is explicit because type inference fails for `Omit<Options, "website">`
        const secretState = SecretState.from(userId, key, this.stateProvider, encryptor$);
        // rollover should occur once the user key is available for decryption
        const canDecrypt$ = this.keyService.userKey$(userId).pipe((0,external_rxjs_namespaceObject.map)((key) => key !== null));
        const rolloverState = new BufferedState(this.stateProvider, this.rolloverKey, secretState, canDecrypt$);
        // cast through unknown required because there's no way to prove to
        // the compiler that `OptionsClassifier` runs within the buffer wrapping
        // the secret state.
        return rolloverState;
    }
    createContext(configuration, settings) {
        return new forwarder_context_ForwarderContext(configuration, settings, this.i18nService);
    }
    createForwardingAddress(configuration, settings) {
        const context = this.createContext(configuration, settings);
        const rpc = new create_forwarding_address_CreateForwardingAddressRpc(configuration, context);
        return rpc;
    }
    getAccountId(configuration, settings) {
        if (!configuration.forwarder.getAccountId) {
            return null;
        }
        const context = this.createContext(configuration, settings);
        const rpc = new get_account_id_GetAccountIdRpc(configuration, context);
        return rpc;
    }
}

;// ../../libs/tools/generator/core/src/strategies/storage.ts

/** plaintext password generation options */
const PASSWORD_SETTINGS = new UserKeyDefinition(GENERATOR_DISK, "passwordGeneratorSettings", {
    deserializer: (value) => value,
    clearOn: [],
});
/** plaintext passphrase generation options */
const PASSPHRASE_SETTINGS = new UserKeyDefinition(GENERATOR_DISK, "passphraseGeneratorSettings", {
    deserializer: (value) => value,
    clearOn: [],
});
/** plaintext username generation options */
const EFF_USERNAME_SETTINGS = new UserKeyDefinition(GENERATOR_DISK, "effUsernameGeneratorSettings", {
    deserializer: (value) => value,
    clearOn: [],
});
/** plaintext configuration for a domain catch-all address. */
const CATCHALL_SETTINGS = new UserKeyDefinition(GENERATOR_DISK, "catchallGeneratorSettings", {
    deserializer: (value) => value,
    clearOn: [],
});
/** plaintext configuration for an email subaddress. */
const SUBADDRESS_SETTINGS = new UserKeyDefinition(GENERATOR_DISK, "subaddressGeneratorSettings", {
    deserializer: (value) => value,
    clearOn: [],
});

;// ../../libs/tools/generator/core/src/strategies/passphrase-generator-strategy.ts
var passphrase_generator_strategy_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore






/** Generates passphrases composed of random words */
class PassphraseGeneratorStrategy {
    /** instantiates the password generator strategy.
     *  @param legacy generates the passphrase
     *  @param stateProvider provides durable state
     */
    constructor(randomizer, stateProvider) {
        this.randomizer = randomizer;
        this.stateProvider = stateProvider;
        // configuration
        this.durableState = sharedStateByUserId(PASSPHRASE_SETTINGS, this.stateProvider);
        this.defaults$ = observe$PerUserId(() => DefaultPassphraseGenerationOptions);
        this.policy = policy_type_enum_PolicyType.PasswordGenerator;
    }
    toEvaluator() {
        return mapPolicyToEvaluator({
            type: policy_type_enum_PolicyType.PasswordGenerator,
            disabledValue: Object.freeze({
                minNumberWords: 0,
                capitalize: false,
                includeNumber: false,
            }),
            combine: passphraseLeastPrivilege,
            createEvaluator: (policy) => new PassphraseGeneratorOptionsEvaluator(policy),
        });
    }
    // algorithm
    generate(options) {
        return passphrase_generator_strategy_awaiter(this, void 0, void 0, function* () {
            const request = optionsToEffWordListRequest(options);
            return this.randomizer.randomEffLongWords(request);
        });
    }
}

;// ../../libs/tools/generator/core/src/strategies/password-generator-strategy.ts
var password_generator_strategy_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};






/** Generates passwords composed of random characters */
class PasswordGeneratorStrategy {
    /** instantiates the password generator strategy.
     *  @param legacy generates the password
     */
    constructor(randomizer, stateProvider) {
        this.randomizer = randomizer;
        this.stateProvider = stateProvider;
        // configuration
        this.durableState = sharedStateByUserId(PASSWORD_SETTINGS, this.stateProvider);
        this.defaults$ = observe$PerUserId(() => DefaultPasswordGenerationOptions);
        this.policy = policy_type_enum_PolicyType.PasswordGenerator;
    }
    toEvaluator() {
        return mapPolicyToEvaluator({
            type: policy_type_enum_PolicyType.PasswordGenerator,
            disabledValue: {
                minLength: 0,
                useUppercase: false,
                useLowercase: false,
                useNumbers: false,
                numberCount: 0,
                useSpecial: false,
                specialCount: 0,
            },
            combine: passwordLeastPrivilege,
            createEvaluator: (policy) => new PasswordGeneratorOptionsEvaluator(policy),
        });
    }
    // algorithm
    generate(options) {
        return password_generator_strategy_awaiter(this, void 0, void 0, function* () {
            const request = optionsToRandomAsciiRequest(options);
            const result = yield this.randomizer.randomAscii(request);
            return result;
        });
    }
}

;// ../../libs/tools/generator/core/src/strategies/catchall-generator-strategy.ts
var catchall_generator_strategy_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore





/** Strategy for creating usernames using a catchall email address */
class CatchallGeneratorStrategy {
    /** Instantiates the generation strategy
     *  @param usernameService generates a catchall address for a domain
     */
    constructor(emailCalculator, emailRandomizer, stateProvider, defaultOptions = DefaultCatchallOptions) {
        this.emailCalculator = emailCalculator;
        this.emailRandomizer = emailRandomizer;
        this.stateProvider = stateProvider;
        this.defaultOptions = defaultOptions;
        // configuration
        this.durableState = sharedStateByUserId(CATCHALL_SETTINGS, this.stateProvider);
        this.defaults$ = observe$PerUserId(() => this.defaultOptions);
        this.toEvaluator = newDefaultEvaluator();
        this.policy = policy_type_enum_PolicyType.PasswordGenerator;
    }
    // algorithm
    generate(options) {
        return catchall_generator_strategy_awaiter(this, void 0, void 0, function* () {
            if (options.catchallType == null) {
                options.catchallType = "random";
            }
            if (options.catchallType === "website-name") {
                return yield this.emailCalculator.concatenate(options.website, options.catchallDomain);
            }
            return this.emailRandomizer.randomAsciiCatchall(options.catchallDomain);
        });
    }
}

;// ../../libs/tools/generator/core/src/strategies/subaddress-generator-strategy.ts
var subaddress_generator_strategy_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore





/** Strategy for creating an email subaddress
 *  @remarks The subaddress is the part following the `+`.
 *  For example, if the email address is `jd+xyz@domain.io`,
 *  the subaddress is `xyz`.
 */
class SubaddressGeneratorStrategy {
    /** Instantiates the generation strategy
     *  @param usernameService generates an email subaddress from an email address
     */
    constructor(emailCalculator, emailRandomizer, stateProvider, defaultOptions = DefaultSubaddressOptions) {
        this.emailCalculator = emailCalculator;
        this.emailRandomizer = emailRandomizer;
        this.stateProvider = stateProvider;
        this.defaultOptions = defaultOptions;
        // configuration
        this.durableState = sharedStateByUserId(SUBADDRESS_SETTINGS, this.stateProvider);
        this.defaults$ = observe$PerUserId(() => this.defaultOptions);
        this.toEvaluator = newDefaultEvaluator();
        this.policy = policy_type_enum_PolicyType.PasswordGenerator;
    }
    // algorithm
    generate(options) {
        return subaddress_generator_strategy_awaiter(this, void 0, void 0, function* () {
            if (options.subaddressType == null) {
                options.subaddressType = "random";
            }
            if (options.subaddressType === "website-name") {
                return this.emailCalculator.appendToSubaddress(options.website, options.subaddressEmail);
            }
            return this.emailRandomizer.randomAsciiSubaddress(options.subaddressEmail);
        });
    }
}

;// ../../libs/tools/generator/core/src/strategies/eff-username-generator-strategy.ts
var eff_username_generator_strategy_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};





const UsernameDigits = Object.freeze({
    enabled: 4,
    disabled: 0,
});
/** Strategy for creating usernames from the EFF wordlist */
class EffUsernameGeneratorStrategy {
    /** Instantiates the generation strategy
     *  @param usernameService generates a username from EFF word list
     */
    constructor(randomizer, stateProvider, defaultOptions = DefaultEffUsernameOptions) {
        this.randomizer = randomizer;
        this.stateProvider = stateProvider;
        this.defaultOptions = defaultOptions;
        // configuration
        this.durableState = sharedStateByUserId(EFF_USERNAME_SETTINGS, this.stateProvider);
        this.defaults$ = observe$PerUserId(() => this.defaultOptions);
        this.toEvaluator = newDefaultEvaluator();
        this.policy = policy_type_enum_PolicyType.PasswordGenerator;
    }
    // algorithm
    generate(options) {
        return eff_username_generator_strategy_awaiter(this, void 0, void 0, function* () {
            var _a, _b;
            const casing = ((_a = options.wordCapitalize) !== null && _a !== void 0 ? _a : DefaultEffUsernameOptions.wordCapitalize)
                ? "TitleCase"
                : "lowercase";
            const digits = ((_b = options.wordIncludeNumber) !== null && _b !== void 0 ? _b : DefaultEffUsernameOptions.wordIncludeNumber)
                ? UsernameDigits.enabled
                : UsernameDigits.disabled;
            const word = yield this.randomizer.randomWords({ numberOfWords: 1, casing, digits });
            return word;
        });
    }
}

;// ../../libs/tools/generator/core/src/strategies/index.ts







;// ../../libs/tools/generator/core/src/index.ts
// The root module interface has API stability guarantees







// These internal interfacess are exposed for use by other generator modules
// They are unstable and may change arbitrarily








;// ./src/tools/generate.command.ts
var generate_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore





class GenerateCommand {
    constructor(passwordGenerationService, tokenService, accountService) {
        this.passwordGenerationService = passwordGenerationService;
        this.tokenService = tokenService;
        this.accountService = accountService;
    }
    run(cmdOptions) {
        return generate_command_awaiter(this, void 0, void 0, function* () {
            const normalizedOptions = new generate_command_Options(cmdOptions);
            const options = {
                uppercase: normalizedOptions.uppercase,
                lowercase: normalizedOptions.lowercase,
                number: normalizedOptions.number,
                special: normalizedOptions.special,
                length: normalizedOptions.length,
                type: normalizedOptions.type,
                wordSeparator: normalizedOptions.separator,
                numWords: normalizedOptions.words,
                capitalize: normalizedOptions.capitalize,
                includeNumber: normalizedOptions.includeNumber,
                minNumber: normalizedOptions.minNumber,
                minSpecial: normalizedOptions.minSpecial,
                ambiguous: !normalizedOptions.ambiguous,
            };
            const shouldEnforceOptions = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.switchMap)((account) => {
                if (account == null) {
                    return (0,external_rxjs_namespaceObject.of)(false);
                }
                return this.tokenService.hasAccessToken$(account.id);
            })));
            const enforcedOptions = shouldEnforceOptions
                ? (yield this.passwordGenerationService.enforcePasswordGeneratorPoliciesOnOptions(options))[0]
                : options;
            const password = yield this.passwordGenerationService.generatePassword(enforcedOptions);
            const res = new StringResponse(password);
            return response_Response.success(res);
        });
    }
}
class generate_command_Options {
    constructor(passedOptions) {
        this.uppercase = CliUtils.convertBooleanOption(passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.uppercase);
        this.lowercase = CliUtils.convertBooleanOption(passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.lowercase);
        this.number = CliUtils.convertBooleanOption(passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.number);
        this.special = CliUtils.convertBooleanOption(passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.special);
        this.capitalize = CliUtils.convertBooleanOption(passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.capitalize);
        this.includeNumber = CliUtils.convertBooleanOption(passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.includeNumber);
        this.ambiguous = CliUtils.convertBooleanOption(passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.ambiguous);
        this.length = CliUtils.convertNumberOption(passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.length, DefaultPasswordGenerationOptions.length);
        this.type = (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.passphrase) ? "passphrase" : "password";
        this.separator = CliUtils.convertStringOption(passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.separator, DefaultPassphraseGenerationOptions.wordSeparator);
        this.words = CliUtils.convertNumberOption(passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.words, DefaultPassphraseGenerationOptions.numWords);
        this.minNumber = CliUtils.convertNumberOption(passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.minNumber, DefaultPasswordGenerationOptions.minNumber);
        this.minSpecial = CliUtils.convertNumberOption(passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.minSpecial, DefaultPasswordGenerationOptions.minSpecial);
        if (!this.uppercase && !this.lowercase && !this.special && !this.number) {
            this.lowercase = true;
            this.uppercase = true;
            this.number = true;
        }
        if (this.length < 5) {
            this.length = 5;
        }
        if (this.words < 3) {
            this.words = 3;
        }
        if (this.separator === "space") {
            this.separator = " ";
        }
        else if (this.separator === "empty") {
            this.separator = "";
        }
        else if (this.separator != null && this.separator.length > 1) {
            this.separator = this.separator[0];
        }
    }
}

;// ./src/vault/sync.command.ts
var sync_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};




class SyncCommand {
    constructor(syncService) {
        this.syncService = syncService;
    }
    run(cmdOptions) {
        return sync_command_awaiter(this, void 0, void 0, function* () {
            const normalizedOptions = new sync_command_Options(cmdOptions);
            if (normalizedOptions.last) {
                return yield this.getLastSync();
            }
            try {
                yield this.syncService.fullSync(normalizedOptions.force, true);
                const res = new MessageResponse("Syncing complete.", null);
                return response_Response.success(res);
            }
            catch (e) {
                const response = response_Response.error(e);
                response.message = "Syncing failed: " + response.message;
                return response;
            }
        });
    }
    getLastSync() {
        return sync_command_awaiter(this, void 0, void 0, function* () {
            const lastSyncDate = yield this.syncService.getLastSync();
            const res = new StringResponse(lastSyncDate == null ? null : lastSyncDate.toISOString());
            return response_Response.success(res);
        });
    }
}
class sync_command_Options {
    constructor(passedOptions) {
        this.last = CliUtils.convertBooleanOption(passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.last);
        this.force = CliUtils.convertBooleanOption(passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.force);
    }
}

;// ./src/program.ts
var program_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore



















const program_writeLn = CliUtils.writeLn;
class Program extends BaseProgram {
    register() {
        return program_awaiter(this, void 0, void 0, function* () {
            external_commander_namespaceObject.program
                .option("--pretty", "Format output. JSON is tabbed with two spaces.")
                .option("--raw", "Return raw output instead of a descriptive message.")
                .option("--response", "Return a JSON formatted version of response output.")
                .option("--cleanexit", "Exit with a success exit code (0) unless an error is thrown.")
                .option("--quiet", "Don't return anything to stdout.")
                .option("--nointeraction", "Do not prompt for interactive user input.")
                .option("--session <session>", "Pass session key instead of reading from env.")
                .version(yield this.serviceContainer.platformUtilsService.getApplicationVersion(), "-v, --version");
            external_commander_namespaceObject.program.on("option:pretty", () => {
                process.env.BW_PRETTY = "true";
            });
            external_commander_namespaceObject.program.on("option:raw", () => {
                process.env.BW_RAW = "true";
            });
            external_commander_namespaceObject.program.on("option:quiet", () => {
                process.env.BW_QUIET = "true";
            });
            external_commander_namespaceObject.program.on("option:response", () => {
                process.env.BW_RESPONSE = "true";
            });
            external_commander_namespaceObject.program.on("option:cleanexit", () => {
                process.env.BW_CLEANEXIT = "true";
            });
            external_commander_namespaceObject.program.on("option:nointeraction", () => {
                process.env.BW_NOINTERACTION = "true";
            });
            external_commander_namespaceObject.program.on("option:session", (key) => {
                process.env.BW_SESSION = key;
            });
            external_commander_namespaceObject.program.on("command:*", () => {
                program_writeLn(external_chalk_namespaceObject.redBright("Invalid command: " + external_commander_namespaceObject.program.args.join(" ")), false, true);
                program_writeLn("See --help for a list of available commands.", true, true);
                process.exitCode = 1;
            });
            external_commander_namespaceObject.program.on("--help", () => {
                program_writeLn(external_chalk_namespaceObject.yellowBright("\n  Tip: Managing and retrieving secrets for dev environments is easier with Bitwarden Secrets Manager. Learn more under https://bitwarden.com/products/secrets-manager/"));
                program_writeLn("\n  Examples:");
                program_writeLn("");
                program_writeLn("    bw login");
                program_writeLn("    bw lock");
                program_writeLn("    bw unlock myPassword321");
                program_writeLn("    bw list --help");
                program_writeLn("    bw list items --search google");
                program_writeLn("    bw get item 99ee88d2-6046-4ea7-92c2-acac464b1412");
                program_writeLn("    bw get password google.com");
                program_writeLn('    echo \'{"name":"My Folder"}\' | bw encode');
                program_writeLn("    bw create folder eyJuYW1lIjoiTXkgRm9sZGVyIn0K");
                program_writeLn("    bw edit folder c7c7b60b-9c61-40f2-8ccd-36c49595ed72 eyJuYW1lIjoiTXkgRm9sZGVyMiJ9Cg==");
                program_writeLn("    bw delete item 99ee88d2-6046-4ea7-92c2-acac464b1412");
                program_writeLn("    bw archive item 99ee88d2-6046-4ea7-92c2-acac464b1412");
                program_writeLn("    bw generate -lusn --length 18");
                program_writeLn("    bw config server https://bitwarden.example.com");
                program_writeLn("    bw send -f ./file.ext");
                program_writeLn('    bw send "text to send"');
                program_writeLn('    echo "text to send" | bw send');
                program_writeLn("    bw receive https://vault.bitwarden.com/#/send/rg3iuoS_Akm2gqy6ADRHmg/Ht7dYjsqjmgqUM3rjzZDSQ");
                program_writeLn("", true);
            });
            external_commander_namespaceObject.program
                .command("sdk-version")
                .description("Print the SDK version.")
                .action(() => program_awaiter(this, void 0, void 0, function* () {
                const sdkVersion = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.serviceContainer.sdkService.version$);
                program_writeLn(sdkVersion, true);
            }));
            external_commander_namespaceObject.program
                .command("login [email] [password]")
                .description("Log into a user account.")
                .option("--method <method>", "Two-step login method.")
                .option("--code <code>", "Two-step login code.")
                .option("--sso [identifier]", "Log in with Single-Sign On with optional organization identifier.")
                .option("--apikey", "Log in with an Api Key.")
                .option("--passwordenv <passwordenv>", "Environment variable storing your password")
                .option("--passwordfile <passwordfile>", "Path to a file containing your password as its first line")
                .option("--check", "Check login status.", () => program_awaiter(this, void 0, void 0, function* () {
                const authed = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.serviceContainer.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.switchMap)((account) => {
                    if (account == null) {
                        return (0,external_rxjs_namespaceObject.of)(false);
                    }
                    return this.serviceContainer.tokenService.hasAccessToken$(account.id);
                })));
                if (authed) {
                    const res = new MessageResponse("You are logged in!", null);
                    this.processResponse(response_Response.success(res), true);
                }
                this.processResponse(response_Response.error("You are not logged in."), true);
            }))
                .on("--help", () => {
                program_writeLn("\n  Notes:");
                program_writeLn("");
                program_writeLn("    See docs for valid `method` enum values.");
                program_writeLn("");
                program_writeLn("    Pass `--raw` option to only return the session key.");
                program_writeLn("");
                program_writeLn("  Examples:");
                program_writeLn("");
                program_writeLn("    bw login");
                program_writeLn("    bw login john@example.com myPassword321 --raw");
                program_writeLn("    bw login john@example.com myPassword321 --method 1 --code 249213");
                program_writeLn("    bw login --sso");
                program_writeLn("", true);
            })
                .action((email, password, options) => program_awaiter(this, void 0, void 0, function* () {
                if (!options.check) {
                    yield this.exitIfAuthed();
                    const command = new LoginCommand(this.serviceContainer.loginStrategyService, this.serviceContainer.authService, this.serviceContainer.twoFactorApiService, this.serviceContainer.cryptoFunctionService, this.serviceContainer.environmentService, this.serviceContainer.passwordGenerationService, this.serviceContainer.platformUtilsService, this.serviceContainer.accountService, this.serviceContainer.twoFactorService, this.serviceContainer.syncService, this.serviceContainer.keyConnectorService, () => program_awaiter(this, void 0, void 0, function* () { return yield this.serviceContainer.logout(); }), this.serviceContainer.ssoUrlService, this.serviceContainer.i18nService, this.serviceContainer.masterPasswordService, this.serviceContainer.userDecryptionOptionsService, this.serviceContainer.encryptedMigrator);
                    const response = yield command.run(email, password, options);
                    this.processResponse(response, true);
                }
            }));
            external_commander_namespaceObject.program
                .command("logout")
                .description("Log out of the current user account.")
                .on("--help", () => {
                program_writeLn("\n  Examples:");
                program_writeLn("");
                program_writeLn("    bw logout");
                program_writeLn("", true);
            })
                .action((cmd) => program_awaiter(this, void 0, void 0, function* () {
                yield this.exitIfNotAuthed();
                const command = new LogoutCommand(this.serviceContainer.authService, this.serviceContainer.i18nService, () => program_awaiter(this, void 0, void 0, function* () { return yield this.serviceContainer.logout(); }));
                const response = yield command.run();
                this.processResponse(response);
            }));
            external_commander_namespaceObject.program
                .command("lock")
                .description("Lock the vault and destroy active session keys.")
                .on("--help", () => {
                program_writeLn("\n  Examples:");
                program_writeLn("");
                program_writeLn("    bw lock");
                program_writeLn("", true);
            })
                .action((cmd) => program_awaiter(this, void 0, void 0, function* () {
                const userId = yield this.exitIfNotAuthed();
                if (yield this.serviceContainer.keyConnectorService.getUsesKeyConnector(userId)) {
                    const logoutCommand = new LogoutCommand(this.serviceContainer.authService, this.serviceContainer.i18nService, () => program_awaiter(this, void 0, void 0, function* () { return yield this.serviceContainer.logout(); }));
                    yield logoutCommand.run();
                    this.processResponse(response_Response.error("You cannot lock your vault because you are using Key Connector. " +
                        "To protect your vault, you have been logged out."), true);
                    return;
                }
                const command = new LockCommand(this.serviceContainer.lockService, this.serviceContainer.accountService);
                const response = yield command.run();
                this.processResponse(response);
            }));
            external_commander_namespaceObject.program
                .command("unlock [password]")
                .description("Unlock the vault and return a new session key.")
                .on("--help", () => {
                program_writeLn("\n  Notes:");
                program_writeLn("");
                program_writeLn("    After unlocking, any previous session keys will no longer be valid.");
                program_writeLn("");
                program_writeLn("    Pass `--raw` option to only return the session key.");
                program_writeLn("");
                program_writeLn("  Examples:");
                program_writeLn("");
                program_writeLn("    bw unlock");
                program_writeLn("    bw unlock myPassword321");
                program_writeLn("    bw unlock myPassword321 --raw");
                program_writeLn("", true);
            })
                .option("--check", "Check lock status.", () => program_awaiter(this, void 0, void 0, function* () {
                var _a;
                yield this.exitIfNotAuthed();
                const userId = (_a = (yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.serviceContainer.accountService.activeAccount$))) === null || _a === void 0 ? void 0 : _a.id;
                yield this.serviceContainer.userAutoUnlockKeyService.setUserKeyInMemoryIfAutoUserKeySet(userId);
                const authStatus = yield this.serviceContainer.authService.getAuthStatus();
                if (authStatus === authentication_status_AuthenticationStatus.Unlocked) {
                    const res = new MessageResponse("Vault is unlocked!", null);
                    this.processResponse(response_Response.success(res), true);
                }
                else {
                    this.processResponse(response_Response.error("Vault is locked."), true);
                }
            }))
                .option("--passwordenv <passwordenv>", "Environment variable storing your password")
                .option("--passwordfile <passwordfile>", "Path to a file containing your password as its first line")
                .action((password, cmd) => program_awaiter(this, void 0, void 0, function* () {
                if (!cmd.check) {
                    yield this.exitIfNotAuthed();
                    const command = new UnlockCommand(this.serviceContainer.accountService, this.serviceContainer.keyService, this.serviceContainer.cryptoFunctionService, this.serviceContainer.logService, this.serviceContainer.keyConnectorService, this.serviceContainer.environmentService, this.serviceContainer.organizationApiService, () => program_awaiter(this, void 0, void 0, function* () { return yield this.serviceContainer.logout(); }), this.serviceContainer.i18nService, this.serviceContainer.encryptedMigrator, this.serviceContainer.masterPasswordUnlockService, this.serviceContainer.unlockService, this.serviceContainer.configService);
                    const response = yield command.run(password, cmd);
                    this.processResponse(response);
                }
            }));
            external_commander_namespaceObject.program
                .command("sync")
                .description("Pull the latest vault data from server.")
                .option("-f, --force", "Force a full sync.")
                .option("--last", "Get the last sync date.")
                .on("--help", () => {
                program_writeLn("\n  Examples:");
                program_writeLn("");
                program_writeLn("    bw sync");
                program_writeLn("    bw sync -f");
                program_writeLn("    bw sync --last");
                program_writeLn("", true);
            })
                .action((cmd) => program_awaiter(this, void 0, void 0, function* () {
                yield this.exitIfNotAuthed();
                const command = new SyncCommand(this.serviceContainer.syncService);
                const response = yield command.run(cmd);
                this.processResponse(response);
            }));
            external_commander_namespaceObject.program
                .command("generate")
                .description("Generate a password/passphrase.")
                .option("-u, --uppercase", "Include uppercase characters.")
                .option("-l, --lowercase", "Include lowercase characters.")
                .option("-n, --number", "Include numeric characters.")
                .option("-s, --special", "Include special characters.")
                .option("-p, --passphrase", "Generate a passphrase.")
                .option("--length <length>", "Length of the password.")
                .option("--words <words>", "Number of words.")
                .option("--minNumber <count>", "Minimum number of numeric characters.")
                .option("--minSpecial <count>", "Minimum number of special characters.")
                .option("--separator <separator>", "Word separator.")
                .option("-c, --capitalize", "Title case passphrase.")
                .option("--includeNumber", "Passphrase includes number.")
                .option("--ambiguous", "Avoid ambiguous characters.")
                .on("--help", () => {
                program_writeLn("\n  Notes:");
                program_writeLn("");
                program_writeLn("    Default options are `-uln --length 14`.");
                program_writeLn("");
                program_writeLn("    Minimum `length` is 5.");
                program_writeLn("");
                program_writeLn("    Minimum `words` is 3.");
                program_writeLn("");
                program_writeLn("  Examples:");
                program_writeLn("");
                program_writeLn("    bw generate");
                program_writeLn("    bw generate -u -l --length 18");
                program_writeLn("    bw generate -ulns --length 25");
                program_writeLn("    bw generate -ul");
                program_writeLn("    bw generate -p --separator _");
                program_writeLn("    bw generate -p --words 5 --separator space");
                program_writeLn("    bw generate -p --words 5 --separator empty");
                program_writeLn("", true);
            })
                .action((options) => program_awaiter(this, void 0, void 0, function* () {
                const command = new GenerateCommand(this.serviceContainer.passwordGenerationService, this.serviceContainer.tokenService, this.serviceContainer.accountService);
                const response = yield command.run(options);
                this.processResponse(response);
            }));
            external_commander_namespaceObject.program
                .command("encode")
                .description("Base 64 encode stdin.")
                .on("--help", () => {
                program_writeLn("\n  Notes:");
                program_writeLn("");
                program_writeLn("    Use to create `encodedJson` for `create` and `edit` commands.");
                program_writeLn("");
                program_writeLn("  Examples:");
                program_writeLn("");
                program_writeLn('    echo \'{"name":"My Folder"}\' | bw encode');
                program_writeLn("", true);
            })
                .action(() => program_awaiter(this, void 0, void 0, function* () {
                const command = new EncodeCommand();
                const response = yield command.run();
                this.processResponse(response);
            }));
            external_commander_namespaceObject.program
                .command("config <setting> [value]")
                .description("Configure CLI settings.")
                .option("--web-vault <url>", "Provides a custom web vault URL that differs from the base URL.")
                .option("--api <url>", "Provides a custom API URL that differs from the base URL.")
                .option("--identity <url>", "Provides a custom identity URL that differs from the base URL.")
                .option("--icons <url>", "Provides a custom icons service URL that differs from the base URL.")
                .option("--notifications <url>", "Provides a custom notifications URL that differs from the base URL.")
                .option("--events <url>", "Provides a custom events URL that differs from the base URL.")
                .option("--key-connector <url>", "Provides the URL for your Key Connector server.")
                .on("--help", () => {
                program_writeLn("\n  Settings:");
                program_writeLn("");
                program_writeLn("    server - On-premises hosted installation URL.");
                program_writeLn("");
                program_writeLn("  Examples:");
                program_writeLn("");
                program_writeLn("    bw config server");
                program_writeLn("    bw config server https://bw.company.com");
                program_writeLn("    bw config server bitwarden.com");
                program_writeLn("    bw config server --api http://localhost:4000 --identity http://localhost:33656");
                program_writeLn("", true);
            })
                .action((setting, value, options) => program_awaiter(this, void 0, void 0, function* () {
                const command = new ConfigCommand(this.serviceContainer.environmentService, this.serviceContainer.accountService);
                const response = yield command.run(setting, value, options);
                this.processResponse(response);
            }));
            external_commander_namespaceObject.program
                .command("update")
                .description("Check for updates.")
                .on("--help", () => {
                program_writeLn("\n  Notes:");
                program_writeLn("");
                program_writeLn("    Returns the URL to download the newest version of this CLI tool.");
                program_writeLn("");
                program_writeLn("    Use the `--raw` option to return only the download URL for the update.");
                program_writeLn("");
                program_writeLn("  Examples:");
                program_writeLn("");
                program_writeLn("    bw update");
                program_writeLn("    bw update --raw");
                program_writeLn("", true);
            })
                .action(() => program_awaiter(this, void 0, void 0, function* () {
                const command = new UpdateCommand(this.serviceContainer.platformUtilsService, this.serviceContainer.apiService);
                const response = yield command.run();
                this.processResponse(response);
            }));
            external_commander_namespaceObject.program
                .command("completion")
                .description("Generate shell completions.")
                .option("--shell <shell>", "Shell to generate completions for.")
                .on("--help", () => {
                program_writeLn("\n  Notes:");
                program_writeLn("");
                program_writeLn("    Valid shells are `zsh`.");
                program_writeLn("");
                program_writeLn("  Examples:");
                program_writeLn("");
                program_writeLn("    bw completion --shell zsh");
                program_writeLn("", true);
            })
                .action((options, cmd) => program_awaiter(this, void 0, void 0, function* () {
                const command = new CompletionCommand();
                const response = yield command.run(options);
                this.processResponse(response);
            }));
            external_commander_namespaceObject.program
                .command("status")
                .description("Show server, last sync, user information, and vault status.")
                .on("--help", () => {
                program_writeLn("");
                program_writeLn("");
                program_writeLn("  Example return value:");
                program_writeLn("");
                program_writeLn("    {");
                program_writeLn('      "serverUrl": "https://bitwarden.example.com",');
                program_writeLn('      "lastSync": "2020-06-16T06:33:51.419Z",');
                program_writeLn('      "userEmail": "user@example.com,');
                program_writeLn('      "userId": "00000000-0000-0000-0000-000000000000",');
                program_writeLn('      "status": "locked"');
                program_writeLn("    }");
                program_writeLn("");
                program_writeLn("  Notes:");
                program_writeLn("");
                program_writeLn("  `status` is one of:");
                program_writeLn("    - `unauthenticated` when you are not logged in");
                program_writeLn("    - `locked` when you are logged in and the vault is locked");
                program_writeLn("    - `unlocked` when you are logged in and the vault is unlocked");
                program_writeLn("", true);
            })
                .action(() => program_awaiter(this, void 0, void 0, function* () {
                const command = new StatusCommand(this.serviceContainer.environmentService, this.serviceContainer.syncService, this.serviceContainer.accountService, this.serviceContainer.authService, this.serviceContainer.userAutoUnlockKeyService);
                const response = yield command.run();
                this.processResponse(response);
            }));
        });
    }
}

;// ../../libs/common/src/tools/send/types/send-type.ts
/** A type of Send. */
const send_type_SendType = Object.freeze({
    /** Send contains plain text. */
    Text: 0,
    /** Send contains a file. */
    File: 1,
});

;// ../../libs/common/src/tools/send/types/auth-type.ts
/** An type of auth necessary to access a Send */
const AuthType = Object.freeze({
    /** Send requires email OTP verification */
    Email: 0,
    /** Send requires a password */
    Password: 1,
    /** Send requires no auth */
    None: 2,
});

;// ../../libs/common/src/tools/send/models/view/send-text.view.ts
class SendTextView {
    constructor(t) {
        this.text = null;
        if (!t) {
            return;
        }
        this.hidden = t.hidden;
    }
    get maskedText() {
        return this.text != null ? "••••••••" : null;
    }
    static fromJSON(json) {
        if (json == null) {
            return null;
        }
        return Object.assign(new SendTextView(), json);
    }
}

;// ./src/tools/send/models/send-text.response.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

class SendTextResponse {
    static template(text = "Text contained in the send.", hidden = false) {
        const req = new SendTextResponse();
        req.text = text;
        req.hidden = hidden;
        return req;
    }
    static toView(text, view = new SendTextView()) {
        if (text == null) {
            return null;
        }
        view.text = text.text;
        view.hidden = text.hidden;
        return view;
    }
    constructor(o) {
        if (o == null) {
            return;
        }
        this.text = o.text;
        this.hidden = o.hidden;
    }
}

;// ../../libs/common/src/tools/send/models/view/send-file.view.ts
class SendFileView {
    constructor(f) {
        this.id = null;
        this.size = null;
        this.sizeName = null;
        this.fileName = null;
        if (!f) {
            return;
        }
        this.id = f.id;
        this.size = f.size;
        this.sizeName = f.sizeName;
    }
    get fileSize() {
        try {
            if (this.size != null) {
                return parseInt(this.size, null);
            }
        }
        catch (_a) {
            // Invalid file size.
        }
        return 0;
    }
    static fromJSON(json) {
        if (json == null) {
            return null;
        }
        return Object.assign(new SendFileView(), json);
    }
}

;// ../../libs/common/src/tools/send/models/view/send.view.ts




class SendView {
    constructor(s) {
        this.id = null;
        this.accessId = null;
        this.name = null;
        this.notes = null;
        this.type = null;
        this.text = new SendTextView();
        this.file = new SendFileView();
        this.maxAccessCount = null;
        this.accessCount = 0;
        this.revisionDate = null;
        this.deletionDate = null;
        this.expirationDate = null;
        this.password = null;
        this.emails = [];
        this.disabled = false;
        this.hideEmail = false;
        this.authType = null;
        if (!s) {
            return;
        }
        this.id = s.id;
        this.accessId = s.accessId;
        this.type = s.type;
        this.authType = s.authType;
        this.maxAccessCount = s.maxAccessCount;
        this.accessCount = s.accessCount;
        this.revisionDate = s.revisionDate;
        this.deletionDate = s.deletionDate;
        this.expirationDate = s.expirationDate;
        this.disabled = s.disabled;
        this.password = s.password;
        this.hideEmail = s.hideEmail;
        this.authType = s.authType;
    }
    get urlB64Key() {
        return utils_Utils.fromArrayToUrlB64(this.key);
    }
    get maxAccessCountReached() {
        if (this.maxAccessCount == null) {
            return false;
        }
        return this.accessCount >= this.maxAccessCount;
    }
    get expired() {
        if (this.expirationDate == null) {
            return false;
        }
        return this.expirationDate <= new Date();
    }
    get pendingDelete() {
        return this.deletionDate <= new Date();
    }
    toJSON() {
        return utils_Utils.merge(Object.assign({}, this), {
            key: utils_Utils.fromBufferToB64(this.key),
        });
    }
    static fromJSON(json) {
        if (json == null) {
            return null;
        }
        return Object.assign(new SendView(), json, {
            key: utils_Utils.fromB64ToArray(json.key),
            cryptoKey: SymmetricCryptoKey.fromJSON(json.cryptoKey),
            text: SendTextView.fromJSON(json.text),
            file: SendFileView.fromJSON(json.file),
            revisionDate: json.revisionDate == null ? null : new Date(json.revisionDate),
            deletionDate: json.deletionDate == null ? null : new Date(json.deletionDate),
            expirationDate: json.expirationDate == null ? null : new Date(json.expirationDate),
        });
    }
}

;// ./src/tools/send/models/send-file.response.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

class SendFileResponse {
    static template(fileName = "file attachment location") {
        const req = new SendFileResponse();
        req.fileName = fileName;
        return req;
    }
    static toView(file, view = new SendFileView()) {
        if (file == null) {
            return null;
        }
        view.id = file.id;
        view.size = file.size;
        view.sizeName = file.sizeName;
        view.fileName = file.fileName;
        return view;
    }
    constructor(o) {
        if (o == null) {
            return;
        }
        this.id = o.id;
        this.size = o.size;
        this.sizeName = o.sizeName;
        this.fileName = o.fileName;
    }
}

;// ./src/tools/send/models/send.response.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore





const dateProperties = [
    utils_Utils.nameOf("deletionDate"),
    utils_Utils.nameOf("expirationDate"),
];
class SendResponse {
    static template(sendType, deleteInDays = 7) {
        const req = new SendResponse();
        req.name = "Send name";
        req.notes = "Some notes about this send.";
        req.type = sendType === send_type_SendType.File ? send_type_SendType.File : send_type_SendType.Text;
        req.text = sendType === send_type_SendType.Text ? SendTextResponse.template() : null;
        req.file = sendType === send_type_SendType.File ? SendFileResponse.template() : null;
        req.maxAccessCount = null;
        req.deletionDate = this.getStandardDeletionDate(deleteInDays);
        req.expirationDate = null;
        req.password = null;
        req.emails = null;
        req.disabled = false;
        req.hideEmail = false;
        return req;
    }
    static toView(send, view = new SendView()) {
        var _a;
        if (send == null) {
            return null;
        }
        view.id = send.id;
        view.accessId = send.accessId;
        view.name = send.name;
        view.notes = send.notes;
        view.key = send.key == null ? null : utils_Utils.fromB64ToArray(send.key);
        view.type = send.type;
        view.file = SendFileResponse.toView(send.file);
        view.text = SendTextResponse.toView(send.text);
        view.maxAccessCount = send.maxAccessCount;
        view.accessCount = send.accessCount;
        view.revisionDate = send.revisionDate;
        view.deletionDate = send.deletionDate;
        view.expirationDate = send.expirationDate;
        view.password = send.password;
        view.emails = (_a = send.emails) !== null && _a !== void 0 ? _a : [];
        view.disabled = send.disabled;
        view.hideEmail = send.hideEmail;
        view.authType = send.authType;
        return view;
    }
    static fromJson(json) {
        return JSON.parse(json, (key, value) => {
            if (dateProperties.includes(key)) {
                return value == null ? null : new Date(value);
            }
            return value;
        });
    }
    static getStandardDeletionDate(days) {
        const d = new Date();
        d.setTime(d.getTime() + days * 86400000); // ms per day
        return d;
    }
    constructor(o, webVaultUrl) {
        var _a;
        this.object = "send";
        if (o == null) {
            return;
        }
        this.id = o.id;
        this.accessId = o.accessId;
        let sendLinkBaseUrl = webVaultUrl;
        if (sendLinkBaseUrl == null) {
            sendLinkBaseUrl = "https://send.bitwarden.com/#";
        }
        else {
            sendLinkBaseUrl += "/#/send/";
        }
        this.accessUrl = sendLinkBaseUrl + this.accessId + "/" + o.urlB64Key;
        this.name = o.name;
        this.notes = o.notes;
        this.key = utils_Utils.fromBufferToB64(o.key);
        this.type = o.type;
        this.maxAccessCount = o.maxAccessCount;
        this.accessCount = o.accessCount;
        this.revisionDate = o.revisionDate;
        this.deletionDate = o.deletionDate;
        this.expirationDate = o.expirationDate;
        this.passwordSet = o.password != null;
        this.emails = (_a = o.emails) !== null && _a !== void 0 ? _a : [];
        this.disabled = o.disabled;
        this.hideEmail = o.hideEmail;
        this.authType = o.authType;
        if (o.type === send_type_SendType.Text && o.text != null) {
            this.text = new SendTextResponse(o.text);
        }
        if (o.type === send_type_SendType.File && o.file != null) {
            this.file = new SendFileResponse(o.file);
        }
    }
}

;// ./src/tools/send/commands/create.command.ts
var create_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore











class SendCreateCommand {
    constructor(sendService, environmentService, sendApiService, accountProfileService, accountService) {
        this.sendService = sendService;
        this.environmentService = environmentService;
        this.sendApiService = sendApiService;
        this.accountProfileService = accountProfileService;
        this.accountService = accountService;
    }
    run(requestJson, cmdOptions) {
        return create_command_awaiter(this, void 0, void 0, function* () {
            let req = null;
            if (process.env.BW_SERVE !== "true" && (requestJson == null || requestJson === "")) {
                requestJson = yield CliUtils.readStdin();
            }
            if (requestJson == null || requestJson === "") {
                return response_Response.badRequest("`requestJson` was not provided.");
            }
            if (typeof requestJson !== "string") {
                req = requestJson;
                req.deletionDate = req.deletionDate == null ? null : new Date(req.deletionDate);
                req.expirationDate = req.expirationDate == null ? null : new Date(req.expirationDate);
            }
            else {
                try {
                    const reqJson = Buffer.from(requestJson, "base64").toString();
                    req = SendResponse.fromJson(reqJson);
                    if (req == null) {
                        throw new Error("Null request");
                    }
                    // FIXME: Remove when updating file. Eslint update
                    // eslint-disable-next-line @typescript-eslint/no-unused-vars
                }
                catch (e) {
                    return response_Response.badRequest("Error parsing the encoded request data.");
                }
            }
            if (req.deletionDate == null ||
                isNaN(new Date(req.deletionDate).getTime()) ||
                new Date(req.deletionDate) <= new Date()) {
                return response_Response.badRequest("Must specify a valid deletion date after the current time");
            }
            if (req.expirationDate != null && isNaN(new Date(req.expirationDate).getTime())) {
                return response_Response.badRequest("Unable to parse expirationDate: " + req.expirationDate);
            }
            const normalizedOptions = new create_command_Options(cmdOptions);
            return this.createSend(req, normalizedOptions);
        });
    }
    createSend(req, options) {
        return create_command_awaiter(this, void 0, void 0, function* () {
            var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
            const filePath = (_b = (_a = req.file) === null || _a === void 0 ? void 0 : _a.fileName) !== null && _b !== void 0 ? _b : options.file;
            const text = (_d = (_c = req.text) === null || _c === void 0 ? void 0 : _c.text) !== null && _d !== void 0 ? _d : options.text;
            const hidden = (_f = (_e = req.text) === null || _e === void 0 ? void 0 : _e.hidden) !== null && _f !== void 0 ? _f : options.hidden;
            const password = (_h = (_g = req.password) !== null && _g !== void 0 ? _g : options.password) !== null && _h !== void 0 ? _h : undefined;
            const emails = (_k = (_j = req.emails) !== null && _j !== void 0 ? _j : options.emails) !== null && _k !== void 0 ? _k : undefined;
            const maxAccessCount = (_l = req.maxAccessCount) !== null && _l !== void 0 ? _l : options.maxAccessCount;
            const hasEmails = emails != null && emails.length > 0;
            const hasPassword = password != null && password.trim().length > 0;
            if (hasEmails && hasPassword) {
                return response_Response.badRequest("--password and --emails are mutually exclusive.");
            }
            req.key = null;
            req.maxAccessCount = maxAccessCount;
            req.emails = emails;
            if (hasEmails) {
                req.authType = AuthType.Email;
            }
            else if (hasPassword) {
                req.authType = AuthType.Password;
            }
            else {
                req.authType = AuthType.None;
            }
            const hasPremium$ = this.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.switchMap)(({ id }) => this.accountProfileService.hasPremiumFromAnySource$(id)));
            switch (req.type) {
                case send_type_SendType.File:
                    if (process.env.BW_SERVE === "true") {
                        return response_Response.error("Creating a file-based Send is unsupported through the `serve` command at this time.");
                    }
                    if (!(yield (0,external_rxjs_namespaceObject.firstValueFrom)(hasPremium$))) {
                        return response_Response.error("Premium status is required to use this feature.");
                    }
                    if (filePath == null) {
                        return response_Response.badRequest("Must specify a file to Send either with the --file option or in the request JSON.");
                    }
                    req.file.fileName = external_path_namespaceObject.basename(filePath);
                    break;
                case send_type_SendType.Text:
                    if (text == null) {
                        return response_Response.badRequest("Must specify text content to Send either with the --text option or in the request JSON.");
                    }
                    req.text = new SendTextResponse();
                    req.text.text = text;
                    req.text.hidden = hidden;
                    break;
                default:
                    return response_Response.badRequest("Unknown Send type " + send_type_SendType[req.type] + ". Valid types are: file, text");
            }
            try {
                let fileBuffer = null;
                if (req.type === send_type_SendType.File) {
                    fileBuffer = NodeUtils.bufferToArrayBuffer(external_fs_namespaceObject.readFileSync(filePath));
                }
                const sendView = SendResponse.toView(req);
                const [encSend, fileData] = yield this.sendService.encrypt(sendView, fileBuffer, password);
                yield this.sendApiService.save([encSend, fileData]);
                const newSend = yield this.sendService.getFromState(encSend.id);
                const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
                const decSend = yield newSend.decrypt(activeUserId);
                const env = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.environmentService.environment$);
                const res = new SendResponse(decSend, env.getWebVaultUrl());
                return response_Response.success(res);
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
}
class create_command_Options {
    constructor(passedOptions) {
        this.file = passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.file;
        this.text = passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.text;
        this.password = passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.password;
        this.emails = passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.emails;
        this.hidden = CliUtils.convertBooleanOption(passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.hidden);
        this.maxAccessCount =
            (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.maxAccessCount) != null ? parseInt(passedOptions.maxAccessCount, null) : null;
    }
}

;// ./src/tools/send/commands/delete.command.ts
var delete_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

class SendDeleteCommand {
    constructor(sendService, sendApiService) {
        this.sendService = sendService;
        this.sendApiService = sendApiService;
    }
    run(id) {
        return delete_command_awaiter(this, void 0, void 0, function* () {
            const send = yield this.sendService.getFromState(id);
            if (send == null) {
                return response_Response.notFound();
            }
            try {
                yield this.sendApiService.delete(id);
                return response_Response.success();
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
}

;// ./src/tools/send/commands/edit.command.ts
var edit_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore







class SendEditCommand {
    constructor(sendService, getCommand, sendApiService, accountProfileService, accountService) {
        this.sendService = sendService;
        this.getCommand = getCommand;
        this.sendApiService = sendApiService;
        this.accountProfileService = accountProfileService;
        this.accountService = accountService;
    }
    run(requestJson, cmdOptions) {
        return edit_command_awaiter(this, void 0, void 0, function* () {
            if (process.env.BW_SERVE !== "true" && (requestJson == null || requestJson === "")) {
                requestJson = yield CliUtils.readStdin();
            }
            if (requestJson == null || requestJson === "") {
                return response_Response.badRequest("`requestJson` was not provided.");
            }
            let req = null;
            if (typeof requestJson !== "string") {
                req = requestJson;
                req.deletionDate = req.deletionDate == null ? null : new Date(req.deletionDate);
                req.expirationDate = req.expirationDate == null ? null : new Date(req.expirationDate);
            }
            else {
                try {
                    const reqJson = Buffer.from(requestJson, "base64").toString();
                    req = SendResponse.fromJson(reqJson);
                    // FIXME: Remove when updating file. Eslint update
                    // eslint-disable-next-line @typescript-eslint/no-unused-vars
                }
                catch (e) {
                    return response_Response.badRequest("Error parsing the encoded request data.");
                }
            }
            const normalizedOptions = new edit_command_Options(cmdOptions);
            req.id = normalizedOptions.itemId || req.id;
            if (normalizedOptions.emails) {
                req.emails = normalizedOptions.emails;
            }
            if (normalizedOptions.password) {
                req.password = normalizedOptions.password;
            }
            if (req.password && (typeof req.password !== "string" || req.password === "")) {
                req.password = undefined;
            }
            // Infer authType based on emails/password (mutually exclusive)
            const hasEmails = req.emails != null && req.emails.length > 0;
            const hasPassword = req.password != null && req.password.trim() !== "";
            if (hasEmails && hasPassword) {
                return response_Response.badRequest("--password and --emails are mutually exclusive.");
            }
            if (hasEmails) {
                req.authType = AuthType.Email;
            }
            else if (hasPassword) {
                req.authType = AuthType.Password;
            }
            else {
                req.authType = AuthType.None;
            }
            if (!req.id) {
                return response_Response.error("`itemid` was not provided.");
            }
            req.id = req.id.toLowerCase();
            const send = yield this.sendService.getFromState(req.id);
            if (send == null) {
                return response_Response.notFound();
            }
            if (send.type !== req.type) {
                return response_Response.badRequest("Cannot change a Send's type");
            }
            const account = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$);
            const canAccessPremium = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountProfileService.hasPremiumFromAnySource$(account.id));
            if (send.type === send_type_SendType.File && !canAccessPremium) {
                return response_Response.error("Premium status is required to use this feature.");
            }
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
            let sendView = yield send.decrypt(activeUserId);
            sendView = SendResponse.toView(req, sendView);
            try {
                const [encSend, encFileData] = yield this.sendService.encrypt(sendView, null, req.password);
                yield this.sendApiService.save([encSend, encFileData]);
            }
            catch (e) {
                return response_Response.error(e);
            }
            return yield this.getCommand.run(send.id, {});
        });
    }
}
class edit_command_Options {
    constructor(passedOptions) {
        this.itemId = (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.itemId) || (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.itemid);
        this.password = passedOptions.password;
        this.emails = passedOptions.emails;
    }
}

;// ./src/models/response/file.response.ts
class FileResponse {
    constructor(data, fileName) {
        this.object = "file";
        this.data = data;
        this.fileName = fileName;
    }
}

;// ./src/commands/download.command.ts
var download_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};



/**
 * Used to download and save attachments
 */
class DownloadCommand {
    /**
     * @param encryptService - Needed for decryption of the retrieved attachment
     * @param apiService - Needed to override the existing nativeFetch which is available as of Node 18, to support proxies
     */
    constructor(encryptService, apiService) {
        this.encryptService = encryptService;
        this.apiService = apiService;
    }
    /**
     * Fetches an attachment via the url, decrypts it's content and saves it to a file
     * @param url - url used to retrieve the attachment
     * @param fileName - filename used when written to disk
     * @param decrypt - Function used to decrypt the response
     * @param output - If output is empty or `--raw` was passed to the initial command the content is output onto stdout
     * @returns Promise<FileResponse>
     */
    saveAttachmentToFile(url, fileName, decrypt, output) {
        return download_command_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.nativeFetch(new Request(url, { headers: { cache: "no-cache" } }));
            if (response.status !== 200) {
                return response_Response.error("A " + response.status + " error occurred while downloading the attachment.");
            }
            try {
                const decBuf = yield decrypt(response);
                if (process.env.BW_SERVE === "true") {
                    const res = new FileResponse(Buffer.from(decBuf), fileName);
                    return response_Response.success(res);
                }
                else {
                    return yield CliUtils.saveResultToFile(Buffer.from(decBuf), output, fileName);
                }
            }
            catch (e) {
                if (typeof e === "string") {
                    return response_Response.error(e);
                }
                else {
                    return response_Response.error("An error occurred while saving the attachment.");
                }
            }
        });
    }
}

;// ./src/tools/send/commands/get.command.ts
var get_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};







class SendGetCommand extends DownloadCommand {
    constructor(sendService, environmentService, searchService, encryptService, apiService, accountService) {
        super(encryptService, apiService);
        this.sendService = sendService;
        this.environmentService = environmentService;
        this.searchService = searchService;
        this.accountService = accountService;
    }
    run(id, options) {
        return get_command_awaiter(this, void 0, void 0, function* () {
            const serveCommand = process.env.BW_SERVE === "true";
            if (serveCommand && !utils_Utils.isGuid(id)) {
                return response_Response.badRequest("`" + id + "` is not a GUID.");
            }
            let sends = yield this.getSendView(id);
            if (sends == null) {
                return response_Response.notFound();
            }
            const env = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.environmentService.environment$);
            const webVaultUrl = env.getWebVaultUrl();
            let filter = (s) => true;
            let selector = (s) => get_command_awaiter(this, void 0, void 0, function* () { return response_Response.success(new SendResponse(s, webVaultUrl)); });
            if (!serveCommand && (options === null || options === void 0 ? void 0 : options.text) != null) {
                filter = (s) => {
                    return filter(s) && s.text != null;
                };
                selector = (s) => get_command_awaiter(this, void 0, void 0, function* () {
                    // Write to stdout and response success so we get the text string only to stdout
                    process.stdout.write(s.text.text);
                    return response_Response.success();
                });
            }
            if (Array.isArray(sends)) {
                if (filter != null) {
                    sends = sends.filter(filter);
                }
                if (sends.length > 1) {
                    return response_Response.multipleResults(sends.map((s) => s.id));
                }
                if (sends.length > 0) {
                    return selector(sends[0]);
                }
                else {
                    return response_Response.notFound();
                }
            }
            return selector(sends);
        });
    }
    getSendView(id) {
        return get_command_awaiter(this, void 0, void 0, function* () {
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
            if (src_isGuid(id)) {
                const send = yield this.sendService.getFromState(id);
                if (send != null) {
                    return yield send.decrypt(activeUserId);
                }
            }
            else if (id.trim() !== "") {
                let sends = yield this.sendService.getAllDecryptedFromState(activeUserId);
                sends = this.searchService.searchSends(sends, id);
                if (sends.length > 1) {
                    return sends;
                }
                else if (sends.length > 0) {
                    return sends[0];
                }
            }
        });
    }
}

;// ./src/models/response/list.response.ts
class list_response_ListResponse {
    constructor(data) {
        this.object = "list";
        this.data = data;
    }
}

;// ./src/tools/send/commands/list.command.ts
var list_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};





class SendListCommand {
    constructor(sendService, environmentService, searchService, accountService) {
        this.sendService = sendService;
        this.environmentService = environmentService;
        this.searchService = searchService;
        this.accountService = accountService;
    }
    run(cmdOptions) {
        return list_command_awaiter(this, void 0, void 0, function* () {
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
            let sends = yield this.sendService.getAllDecryptedFromState(activeUserId);
            const normalizedOptions = new list_command_Options(cmdOptions);
            if (normalizedOptions.search != null && normalizedOptions.search.trim() !== "") {
                sends = this.searchService.searchSends(sends, normalizedOptions.search);
            }
            const env = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.environmentService.environment$);
            const webVaultUrl = env.getWebVaultUrl();
            const res = new list_response_ListResponse(sends.map((s) => new SendResponse(s, webVaultUrl)));
            return response_Response.success(res);
        });
    }
}
class list_command_Options {
    constructor(passedOptions) {
        this.search = passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.search;
    }
}

;// ../../libs/common/src/auth/send-access/models/send-access-token.ts
class SendAccessToken {
    constructor(
    /**
     * The access token string
     */
    token, 
    /**
     * The time (in milliseconds since the epoch) when the token expires
     */
    expiresAt) {
        this.token = token;
        this.expiresAt = expiresAt;
    }
    /** Returns whether the send access token is expired or not
     * Has a 5 second threshold to avoid race conditions with the token
     * expiring in flight
     */
    isExpired(threshold = 5000) {
        return Date.now() >= this.expiresAt - threshold;
    }
    /** Returns how many full seconds remain until expiry. Returns 0 if expired. */
    timeUntilExpirySeconds() {
        return Math.max(0, Math.floor((this.expiresAt - Date.now()) / 1000));
    }
    static fromJson(parsedJson) {
        return new SendAccessToken(parsedJson.token, parsedJson.expiresAt);
    }
    /**
     * Creates a SendAccessToken from a SendAccessTokenResponse.
     * @param sendAccessTokenResponse The SDK response object containing the token and expiry information.
     * @returns A new instance of SendAccessToken.
     * note: we need to convert from the SDK response type to our internal type so that we can
     * be sure it will serialize/deserialize correctly in state provider.
     */
    static fromSendAccessTokenResponse(sendAccessTokenResponse) {
        return new SendAccessToken(sendAccessTokenResponse.token, sendAccessTokenResponse.expiresAt);
    }
}

;// ../../libs/common/src/auth/send-access/models/index.ts


;// ../../libs/common/src/auth/send-access/services/send-access-token-dict.state.ts


const SEND_ACCESS_TOKEN_DICT = KeyDefinition.record(SEND_ACCESS_DISK, "accessTokenDict", {
    deserializer: (sendAccessTokenJson) => {
        return SendAccessToken.fromJson(sendAccessTokenJson);
    },
});

;// ../../libs/common/src/auth/send-access/services/default-send-token.service.ts
var default_send_token_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __rest = (undefined && undefined.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};




class DefaultSendTokenService {
    constructor(globalStateProvider, sdkService, sendPasswordService) {
        this.globalStateProvider = globalStateProvider;
        this.sdkService = sdkService;
        this.sendPasswordService = sendPasswordService;
        this.initializeState();
    }
    initializeState() {
        this.sendAccessTokenDictGlobalState = this.globalStateProvider.get(SEND_ACCESS_TOKEN_DICT);
    }
    tryGetSendAccessToken$(sendId) {
        // Defer the execution to ensure that a cold observable is returned.
        return (0,external_rxjs_namespaceObject.defer)(() => (0,external_rxjs_namespaceObject.from)(this._tryGetSendAccessToken(sendId)));
    }
    _tryGetSendAccessToken(sendId) {
        return default_send_token_service_awaiter(this, void 0, void 0, function* () {
            // Validate the sendId is a non-empty string.
            this.validateSendId(sendId);
            // Check in storage for the access token for the given sendId.
            const sendAccessTokenFromStorage = yield this.getSendAccessTokenFromStorage(sendId);
            if (sendAccessTokenFromStorage != null) {
                // If it is expired, we clear the token from storage and return the expired error
                if (sendAccessTokenFromStorage.isExpired()) {
                    yield this.clearSendAccessTokenFromStorage(sendId);
                    return { kind: "expired" };
                }
                else {
                    // If it is not expired, we return it
                    return sendAccessTokenFromStorage;
                }
            }
            // If we don't have a token in storage, we can try to request a new token from the server.
            const request = {
                sendId: sendId,
            };
            const anonSdkClient = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkService.client$);
            try {
                const result = yield anonSdkClient
                    .auth()
                    .send_access()
                    .request_send_access_token(request);
                // Convert from SDK shape to SendAccessToken so it can be serialized into & out of state provider
                const sendAccessToken = SendAccessToken.fromSendAccessTokenResponse(result);
                // If we get a token back, we need to store it in the global state.
                yield this.setSendAccessTokenInStorage(sendId, sendAccessToken);
                return sendAccessToken;
            }
            catch (error) {
                return this.normalizeSendAccessTokenError(error);
            }
        });
    }
    getSendAccessToken$(sendId, sendCredentials) {
        // Defer the execution to ensure that a cold observable is returned.
        return (0,external_rxjs_namespaceObject.defer)(() => (0,external_rxjs_namespaceObject.from)(this._getSendAccessToken(sendId, sendCredentials)));
    }
    _getSendAccessToken(sendId, sendAccessCredentials) {
        return default_send_token_service_awaiter(this, void 0, void 0, function* () {
            // Validate inputs to account for non-strict TS call sites.
            this.validateCredentialsRequest(sendId, sendAccessCredentials);
            // Convert inputs to SDK request shape
            const request = {
                sendId: sendId,
                sendAccessCredentials: this.convertDomainCredentialsToSdkCredentials(sendAccessCredentials),
            };
            const anonSdkClient = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkService.client$);
            try {
                const result = yield anonSdkClient
                    .auth()
                    .send_access()
                    .request_send_access_token(request);
                // Convert from SDK interface to SendAccessToken class so it can be serialized into & out of state provider
                const sendAccessToken = SendAccessToken.fromSendAccessTokenResponse(result);
                // Any time we get a token from the server, we need to store it in the global state.
                yield this.setSendAccessTokenInStorage(sendId, sendAccessToken);
                return sendAccessToken;
            }
            catch (error) {
                return this.normalizeSendAccessTokenError(error);
            }
        });
    }
    invalidateSendAccessToken(sendId) {
        return default_send_token_service_awaiter(this, void 0, void 0, function* () {
            yield this.clearSendAccessTokenFromStorage(sendId);
        });
    }
    hashSendPassword(password, keyMaterialUrlB64) {
        return default_send_token_service_awaiter(this, void 0, void 0, function* () {
            // Validate the password and key material
            if (password == null || password.trim() === "") {
                throw new Error("Password must be provided.");
            }
            if (keyMaterialUrlB64 == null || keyMaterialUrlB64.trim() === "") {
                throw new Error("KeyMaterialUrlB64 must be provided.");
            }
            // Convert the base64 URL encoded key material to a Uint8Array
            const keyMaterialUrlB64Array = utils_Utils.fromUrlB64ToArray(keyMaterialUrlB64);
            const sendHashedPasswordArray = yield this.sendPasswordService.hashPassword(password, keyMaterialUrlB64Array);
            // Convert the Uint8Array to a base64 encoded string which is required
            // for the server to be able to compare the password hash.
            const sendHashedPasswordB64 = utils_Utils.fromBufferToB64(sendHashedPasswordArray);
            return sendHashedPasswordB64;
        });
    }
    getSendAccessTokenFromStorage(sendId) {
        return default_send_token_service_awaiter(this, void 0, void 0, function* () {
            if (this.sendAccessTokenDictGlobalState != null) {
                const sendAccessTokenDict = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sendAccessTokenDictGlobalState.state$);
                return sendAccessTokenDict === null || sendAccessTokenDict === void 0 ? void 0 : sendAccessTokenDict[sendId];
            }
            return undefined;
        });
    }
    setSendAccessTokenInStorage(sendId, sendAccessToken) {
        return default_send_token_service_awaiter(this, void 0, void 0, function* () {
            if (this.sendAccessTokenDictGlobalState != null) {
                yield this.sendAccessTokenDictGlobalState.update((sendAccessTokenDict) => {
                    sendAccessTokenDict !== null && sendAccessTokenDict !== void 0 ? sendAccessTokenDict : (sendAccessTokenDict = {}); // Initialize if undefined
                    sendAccessTokenDict[sendId] = sendAccessToken;
                    return sendAccessTokenDict;
                }, {
                    // only update if the value is different (to avoid unnecessary writes)
                    shouldUpdate: (prevDict) => {
                        const prevSendAccessToken = prevDict === null || prevDict === void 0 ? void 0 : prevDict[sendId];
                        return ((prevSendAccessToken === null || prevSendAccessToken === void 0 ? void 0 : prevSendAccessToken.token) !== sendAccessToken.token ||
                            (prevSendAccessToken === null || prevSendAccessToken === void 0 ? void 0 : prevSendAccessToken.expiresAt) !== sendAccessToken.expiresAt);
                    },
                });
            }
        });
    }
    clearSendAccessTokenFromStorage(sendId) {
        return default_send_token_service_awaiter(this, void 0, void 0, function* () {
            if (this.sendAccessTokenDictGlobalState != null) {
                yield this.sendAccessTokenDictGlobalState.update((sendAccessTokenDict) => {
                    if (!sendAccessTokenDict) {
                        // If the dict is empty or undefined, there's nothing to clear
                        return sendAccessTokenDict;
                    }
                    if (sendAccessTokenDict[sendId] == null) {
                        // If the specific sendId does not exist, nothing to clear
                        return sendAccessTokenDict;
                    }
                    // Destructure to omit the specific sendId and get new reference for the rest of the dict for an immutable update
                    // eslint-disable-next-line @typescript-eslint/no-unused-vars
                    const _a = sendAccessTokenDict, _b = sendId, _ = _a[_b], rest = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
                    return rest;
                }, {
                    // only update if the value is defined (to avoid unnecessary writes)
                    shouldUpdate: (prevDict) => (prevDict === null || prevDict === void 0 ? void 0 : prevDict[sendId]) != null,
                });
            }
        });
    }
    /**
     * Normalizes an error from the SDK send access token request process.
     * @param e The error to normalize.
     * @returns A normalized GetSendAccessTokenError.
     */
    normalizeSendAccessTokenError(e) {
        if (this.isSendAccessTokenError(e)) {
            if (e.kind === "unexpected") {
                return { kind: "unexpected_server", error: e.data };
            }
            return { kind: "expected_server", error: e.data };
        }
        if (e instanceof Error) {
            return { kind: "unknown", error: e.message };
        }
        try {
            return { kind: "unknown", error: JSON.stringify(e) };
        }
        catch (_a) {
            return { kind: "unknown", error: "error cannot be stringified" };
        }
    }
    isSendAccessTokenError(e) {
        return (typeof e === "object" &&
            e !== null &&
            "kind" in e &&
            (e.kind === "expected" || e.kind === "unexpected"));
    }
    validateSendId(sendId) {
        if (sendId == null || sendId.trim() === "") {
            throw new Error("sendId must be provided.");
        }
    }
    validateCredentialsRequest(sendId, sendAccessCredentials) {
        this.validateSendId(sendId);
        if (sendAccessCredentials == null) {
            throw new Error("sendAccessCredentials must be provided.");
        }
        if (sendAccessCredentials.kind === "password" && !sendAccessCredentials.passwordHashB64) {
            throw new Error("passwordHashB64 must be provided for password credentials.");
        }
        if (sendAccessCredentials.kind === "email" && !sendAccessCredentials.email) {
            throw new Error("email must be provided for email credentials.");
        }
        if (sendAccessCredentials.kind === "email_otp" &&
            (!sendAccessCredentials.email || !sendAccessCredentials.otp)) {
            throw new Error("email and otp must be provided for email_otp credentials.");
        }
    }
    convertDomainCredentialsToSdkCredentials(sendAccessCredentials) {
        switch (sendAccessCredentials.kind) {
            case "password":
                return {
                    passwordHashB64: sendAccessCredentials.passwordHashB64,
                };
            case "email":
                return {
                    email: sendAccessCredentials.email,
                };
            case "email_otp":
                return {
                    email: sendAccessCredentials.email,
                    otp: sendAccessCredentials.otp,
                };
        }
    }
}

;// ../../libs/common/src/auth/send-access/services/index.ts


;// ../../libs/common/src/auth/send-access/types/invalid-request-errors.type.ts
function isInvalidRequest(e) {
    return e.error === "invalid_request";
}
function isBareInvalidRequest(e) {
    return e.error === "invalid_request" && e.send_access_error_type === undefined;
}
function sendIdRequired(e) {
    return e.error === "invalid_request" && e.send_access_error_type === "send_id_required";
}
function passwordHashB64Required(e) {
    return e.error === "invalid_request" && e.send_access_error_type === "password_hash_b64_required";
}
function emailRequired(e) {
    return e.error === "invalid_request" && e.send_access_error_type === "email_required";
}
function emailAndOtpRequired(e) {
    return e.error === "invalid_request" && e.send_access_error_type === "email_and_otp_required";
}
function isUnknownInvalidRequest(e) {
    return e.error === "invalid_request" && e.send_access_error_type === "unknown";
}

;// ../../libs/common/src/auth/send-access/types/invalid-grant-errors.type.ts
function isInvalidGrant(e) {
    return e.error === "invalid_grant";
}
function isBareInvalidGrant(e) {
    return e.error === "invalid_grant" && e.send_access_error_type === undefined;
}
function sendIdInvalid(e) {
    return e.error === "invalid_grant" && e.send_access_error_type === "send_id_invalid";
}
function passwordHashB64Invalid(e) {
    return e.error === "invalid_grant" && e.send_access_error_type === "password_hash_b64_invalid";
}
function isUnknownInvalidGrant(e) {
    return e.error === "invalid_grant" && e.send_access_error_type === "unknown";
}

;// ../../libs/common/src/auth/send-access/types/index.ts








;// ../../libs/common/src/auth/send-access/index.ts





;// ../../libs/common/src/platform/models/domain/enc-array-buffer.ts
var enc_array_buffer_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


const ENC_TYPE_LENGTH = 1;
const IV_LENGTH = 16;
const MAC_LENGTH = 32;
const MIN_DATA_LENGTH = 1;
class EncArrayBuffer {
    constructor(buffer) {
        this.buffer = buffer;
        this.encryptionType = null;
        this.dataBytes = null;
        this.ivBytes = null;
        this.macBytes = null;
        const encBytes = buffer;
        const encType = encBytes[0];
        switch (encType) {
            case encryption_type_enum_EncryptionType.AesCbc256_HmacSha256_B64: {
                const minimumLength = ENC_TYPE_LENGTH + IV_LENGTH + MAC_LENGTH + MIN_DATA_LENGTH;
                if (encBytes.length < minimumLength) {
                    this.throwDecryptionError();
                }
                this.ivBytes = encBytes.slice(ENC_TYPE_LENGTH, ENC_TYPE_LENGTH + IV_LENGTH);
                this.macBytes = encBytes.slice(ENC_TYPE_LENGTH + IV_LENGTH, ENC_TYPE_LENGTH + IV_LENGTH + MAC_LENGTH);
                this.dataBytes = encBytes.slice(ENC_TYPE_LENGTH + IV_LENGTH + MAC_LENGTH);
                break;
            }
            case encryption_type_enum_EncryptionType.AesCbc256_B64: {
                const minimumLength = ENC_TYPE_LENGTH + IV_LENGTH + MIN_DATA_LENGTH;
                if (encBytes.length < minimumLength) {
                    this.throwDecryptionError();
                }
                this.ivBytes = encBytes.slice(ENC_TYPE_LENGTH, ENC_TYPE_LENGTH + IV_LENGTH);
                this.dataBytes = encBytes.slice(ENC_TYPE_LENGTH + IV_LENGTH);
                break;
            }
            default:
                this.throwDecryptionError();
        }
        this.encryptionType = encType;
    }
    throwDecryptionError() {
        throw new Error("Error parsing encrypted ArrayBuffer: data is corrupted or has an invalid format.");
    }
    static fromParts(encryptionType, iv, data, mac) {
        if (encryptionType == null || iv == null || data == null) {
            throw new Error("encryptionType, iv, and data must be provided");
        }
        switch (encryptionType) {
            case encryption_type_enum_EncryptionType.AesCbc256_B64:
            case encryption_type_enum_EncryptionType.AesCbc256_HmacSha256_B64:
                EncArrayBuffer.validateIvLength(iv);
                EncArrayBuffer.validateMacLength(encryptionType, mac);
                break;
            default:
                throw new Error(`Unknown EncryptionType ${encryptionType} for EncArrayBuffer.fromParts`);
        }
        let macLen = 0;
        if (mac != null) {
            macLen = mac.length;
        }
        const bytes = new Uint8Array(1 + iv.byteLength + macLen + data.byteLength);
        bytes.set([encryptionType], 0);
        bytes.set(iv, 1);
        if (mac != null) {
            bytes.set(mac, 1 + iv.byteLength);
        }
        bytes.set(data, 1 + iv.byteLength + macLen);
        return new EncArrayBuffer(bytes);
    }
    static fromResponse(response) {
        return enc_array_buffer_awaiter(this, void 0, void 0, function* () {
            const buffer = yield response.arrayBuffer();
            if (buffer == null) {
                throw new Error("Cannot create EncArrayBuffer from Response - Response is empty");
            }
            return new EncArrayBuffer(new Uint8Array(buffer));
        });
    }
    static fromB64(b64) {
        const buffer = utils_Utils.fromB64ToArray(b64);
        return new EncArrayBuffer(buffer);
    }
    static validateIvLength(iv) {
        if (iv == null || iv.length !== IV_LENGTH) {
            throw new Error("Invalid IV length");
        }
    }
    static validateMacLength(encType, mac) {
        switch (encType) {
            case encryption_type_enum_EncryptionType.AesCbc256_B64:
                if (mac != null) {
                    throw new Error("mac must not be provided for AesCbc256_B64");
                }
                break;
            case encryption_type_enum_EncryptionType.AesCbc256_HmacSha256_B64:
                if (mac == null || mac.length !== MAC_LENGTH) {
                    throw new Error("Invalid MAC length");
                }
                break;
            default:
                throw new Error("Invalid encryption type and mac combination");
        }
    }
}

;// ../../libs/common/src/tools/send/models/view/send-access.view.ts


class SendAccessView {
    constructor(s) {
        this.id = null;
        this.name = null;
        this.type = null;
        this.text = new SendTextView();
        this.file = new SendFileView();
        this.expirationDate = null;
        this.creatorIdentifier = null;
        if (!s) {
            return;
        }
        this.id = s.id;
        this.type = s.type;
        this.expirationDate = s.expirationDate;
        this.creatorIdentifier = s.creatorIdentifier;
    }
}

;// ../../libs/common/src/tools/send/models/domain/send-file.ts
var send_file_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};



class SendFile extends Domain {
    constructor(obj) {
        super();
        if (obj == null) {
            return;
        }
        this.size = obj.size;
        this.buildDomainModel(this, obj, {
            id: null,
            sizeName: null,
            fileName: null,
        }, ["id", "sizeName"]);
    }
    decrypt(key) {
        return send_file_awaiter(this, void 0, void 0, function* () {
            return yield this.decryptObj(this, new SendFileView(this), ["fileName"], key);
        });
    }
    static fromJSON(obj) {
        if (obj == null) {
            return null;
        }
        return Object.assign(new SendFile(), obj, {
            fileName: enc_string_EncString.fromJSON(obj.fileName),
        });
    }
}

;// ../../libs/common/src/tools/send/models/domain/send-text.ts



class SendText extends Domain {
    constructor(obj) {
        super();
        if (obj == null) {
            return;
        }
        this.hidden = obj.hidden;
        this.buildDomainModel(this, obj, {
            text: null,
        }, []);
    }
    decrypt(key) {
        return this.decryptObj(this, new SendTextView(this), ["text"], key);
    }
    static fromJSON(obj) {
        if (obj == null) {
            return null;
        }
        return Object.assign(new SendText(), obj, {
            text: enc_string_EncString.fromJSON(obj.text),
        });
    }
}

;// ../../libs/common/src/tools/send/models/domain/send-access.ts
var send_access_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};





class SendAccess extends Domain {
    constructor(obj) {
        super();
        if (obj == null) {
            return;
        }
        this.buildDomainModel(this, obj, {
            id: null,
            name: null,
            expirationDate: null,
            creatorIdentifier: null,
        }, ["id", "expirationDate", "creatorIdentifier"]);
        this.type = obj.type;
        switch (this.type) {
            case send_type_SendType.Text:
                this.text = new SendText(obj.text);
                break;
            case send_type_SendType.File:
                this.file = new SendFile(obj.file);
                break;
            default:
                break;
        }
    }
    decrypt(key) {
        return send_access_awaiter(this, void 0, void 0, function* () {
            const model = new SendAccessView(this);
            yield this.decryptObj(this, model, ["name"], key);
            switch (this.type) {
                case send_type_SendType.File:
                    model.file = yield this.file.decrypt(key);
                    break;
                case send_type_SendType.Text:
                    model.text = yield this.text.decrypt(key);
                    break;
                default:
                    break;
            }
            return model;
        });
    }
}

;// ../../libs/common/src/tools/send/models/request/send-access.request.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
class SendAccessRequest {
}

;// ./src/tools/send/models/send-access.response.ts



class SendAccessResponse {
    static template() {
        const req = new SendAccessResponse();
        req.name = "Send name";
        req.type = send_type_SendType.Text;
        req.text = null;
        req.file = null;
        return req;
    }
    constructor(o) {
        this.object = "send-access";
        if (o == null) {
            return;
        }
        this.id = o.id;
        this.name = o.name;
        this.type = o.type;
        if (o.type === send_type_SendType.Text && o.text != null) {
            this.text = new SendTextResponse(o.text);
        }
        if (o.type === send_type_SendType.File && o.file != null) {
            this.file = new SendFileResponse(o.file);
        }
    }
}

;// ./src/tools/send/commands/receive.command.ts
var receive_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
















class SendReceiveCommand extends DownloadCommand {
    constructor(keyService, encryptService, cryptoFunctionService, platformUtilsService, environmentService, sendApiService, apiService, sendTokenService, configService) {
        super(encryptService, apiService);
        this.keyService = keyService;
        this.cryptoFunctionService = cryptoFunctionService;
        this.platformUtilsService = platformUtilsService;
        this.environmentService = environmentService;
        this.sendApiService = sendApiService;
        this.sendTokenService = sendTokenService;
        this.configService = configService;
    }
    run(url, options) {
        return receive_command_awaiter(this, void 0, void 0, function* () {
            this.canInteract = process.env.BW_NOINTERACTION !== "true";
            let urlObject;
            try {
                urlObject = new URL(url);
                // FIXME: Remove when updating file. Eslint update
                // eslint-disable-next-line @typescript-eslint/no-unused-vars
            }
            catch (e) {
                return response_Response.badRequest("Failed to parse the provided Send url");
            }
            const apiUrl = yield this.getApiUrl(urlObject);
            const [id, key] = this.getIdAndKey(urlObject);
            if (utils_Utils.isNullOrWhitespace(id) || utils_Utils.isNullOrWhitespace(key)) {
                return response_Response.badRequest("Failed to parse url, the url provided is not a valid Send url");
            }
            const keyArray = utils_Utils.fromUrlB64ToArray(key);
            const sendEmailOtpEnabled = yield this.configService.getFeatureFlag(feature_flag_enum_FeatureFlag.SendEmailOTP);
            if (sendEmailOtpEnabled) {
                return yield this.attemptV2Access(apiUrl, id, keyArray, options);
            }
            else {
                return yield this.attemptV1Access(apiUrl, id, keyArray, options);
            }
        });
    }
    getIdAndKey(url) {
        const result = url.hash.slice(1).split("/").slice(-2);
        return [result[0], result[1]];
    }
    getApiUrl(url) {
        return receive_command_awaiter(this, void 0, void 0, function* () {
            const env = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.environmentService.environment$);
            const urls = env.getUrls();
            if (url.origin === "https://send.bitwarden.com") {
                return "https://api.bitwarden.com";
            }
            else if (url.origin === urls.api) {
                return url.origin;
            }
            else if (this.platformUtilsService.isDev() && url.origin === urls.webVault) {
                return urls.api;
            }
            else {
                return url.origin + "/api";
            }
        });
    }
    getUnlockedPassword(password, keyArray) {
        return receive_command_awaiter(this, void 0, void 0, function* () {
            const passwordHash = yield this.cryptoFunctionService.pbkdf2(password, keyArray, "sha256", 100000);
            return utils_Utils.fromBufferToB64(passwordHash);
        });
    }
    attemptV1Access(apiUrl, id, keyArray, options) {
        return receive_command_awaiter(this, void 0, void 0, function* () {
            var _a, _b, _c;
            this.sendAccessRequest = new SendAccessRequest();
            let password = options.password;
            if (password == null || password === "") {
                if (options.passwordfile) {
                    password = yield NodeUtils.readFirstLine(options.passwordfile);
                }
                else if (options.passwordenv && process.env[options.passwordenv]) {
                    password = process.env[options.passwordenv];
                }
            }
            if (password != null && password !== "") {
                this.sendAccessRequest.password = yield this.getUnlockedPassword(password, keyArray);
            }
            const response = yield this.sendRequest(apiUrl, id, keyArray);
            if (response instanceof response_Response) {
                return response;
            }
            if (options.obj != null) {
                return response_Response.success(new SendAccessResponse(response));
            }
            switch (response.type) {
                case send_type_SendType.Text:
                    process.stdout.write((_a = response === null || response === void 0 ? void 0 : response.text) === null || _a === void 0 ? void 0 : _a.text);
                    return response_Response.success();
                case send_type_SendType.File: {
                    const downloadData = yield this.sendApiService.getSendFileDownloadData(response, this.sendAccessRequest, apiUrl);
                    const decryptBufferFn = (resp) => receive_command_awaiter(this, void 0, void 0, function* () {
                        const encBuf = yield EncArrayBuffer.fromResponse(resp);
                        return this.encryptService.decryptFileData(encBuf, this.decKey);
                    });
                    return yield this.saveAttachmentToFile(downloadData.url, external_path_namespaceObject.basename((_c = (_b = response === null || response === void 0 ? void 0 : response.file) === null || _b === void 0 ? void 0 : _b.fileName) !== null && _c !== void 0 ? _c : `BitwardenSendFile-${Date.now()}`), decryptBufferFn, options.output);
                }
                default:
                    return response_Response.success(new SendAccessResponse(response));
            }
        });
    }
    attemptV2Access(apiUrl, id, keyArray, options) {
        return receive_command_awaiter(this, void 0, void 0, function* () {
            let authType = AuthType.None;
            const currentResponse = yield this.getTokenWithRetry(id);
            if (currentResponse instanceof SendAccessToken) {
                return yield this.accessSendWithToken(currentResponse, keyArray, apiUrl, options);
            }
            if (currentResponse.kind === "expected_server") {
                const error = currentResponse.error;
                if (emailRequired(error)) {
                    authType = AuthType.Email;
                }
                else if (passwordHashB64Required(error)) {
                    authType = AuthType.Password;
                }
                else if (sendIdInvalid(error)) {
                    return response_Response.notFound();
                }
            }
            else {
                return this.handleError(currentResponse);
            }
            // Handle authentication based on type
            if (authType === AuthType.Email) {
                if (!this.canInteract) {
                    return response_Response.badRequest("Email verification required. Run in interactive mode.");
                }
                return yield this.handleEmailOtpAuth(id, keyArray, apiUrl, options);
            }
            else if (authType === AuthType.Password) {
                return yield this.handlePasswordAuth(id, keyArray, apiUrl, options);
            }
            // The auth layer will immediately return a token for Sends with AuthType.None
            // If this code is reached, something has gone wrong
            if (authType === AuthType.None) {
                return response_Response.error("Could not determine authentication requirements");
            }
            return response_Response.error("Authentication failed");
        });
    }
    getTokenWithRetry(sendId, credentials) {
        return receive_command_awaiter(this, void 0, void 0, function* () {
            let expiredAttempts = 0;
            while (expiredAttempts < 3) {
                const response = credentials
                    ? yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sendTokenService.getSendAccessToken$(sendId, credentials))
                    : yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sendTokenService.tryGetSendAccessToken$(sendId));
                if (response instanceof SendAccessToken) {
                    return response;
                }
                if (response.kind === "expired") {
                    expiredAttempts++;
                    continue;
                }
                // Not expired, return the response for caller to handle
                return response;
            }
            // After 3 expired attempts, return an error response
            return {
                kind: "unknown",
                error: "Send access token has expired and could not be refreshed",
            };
        });
    }
    handleError(error) {
        if (error.kind === "unexpected_server") {
            return response_Response.error("Server error: " + JSON.stringify(error.error));
        }
        return response_Response.error("Error: " + JSON.stringify(error.error));
    }
    promptForOtp(sendId, email) {
        return receive_command_awaiter(this, void 0, void 0, function* () {
            const otpAnswer = yield external_inquirer_namespaceObject.createPromptModule({ output: process.stderr })({
                type: "input",
                name: "otp",
                message: "Enter the verification code sent to your email:",
            });
            return otpAnswer.otp;
        });
    }
    promptForEmail() {
        return receive_command_awaiter(this, void 0, void 0, function* () {
            const emailAnswer = yield external_inquirer_namespaceObject.createPromptModule({ output: process.stderr })({
                type: "input",
                name: "email",
                message: "Enter your email address:",
                validate: (input) => {
                    if (!input || !input.includes("@")) {
                        return "Please enter a valid email address";
                    }
                    return true;
                },
            });
            return emailAnswer.email;
        });
    }
    handleEmailOtpAuth(sendId, keyArray, apiUrl, options) {
        return receive_command_awaiter(this, void 0, void 0, function* () {
            const email = yield this.promptForEmail();
            const emailResponse = yield this.getTokenWithRetry(sendId, {
                kind: "email",
                email: email,
            });
            if (emailResponse instanceof SendAccessToken) {
                /*
                  At this point emailResponse should only be expected to be a GetSendAccessTokenError type,
                  but TS must have a logical branch in case it is a SendAccessToken type. If a valid token is
                  returned by the method above, something has gone wrong.
                 */
                return response_Response.error("Unexpected server response");
            }
            if (emailResponse.kind === "expected_server") {
                const error = emailResponse.error;
                if (emailAndOtpRequired(error)) {
                    const promptResponse = yield this.promptForOtp(sendId, email);
                    // Use retry helper for expired token handling
                    const otpResponse = yield this.getTokenWithRetry(sendId, {
                        kind: "email_otp",
                        email: email,
                        otp: promptResponse,
                    });
                    if (otpResponse instanceof SendAccessToken) {
                        return yield this.accessSendWithToken(otpResponse, keyArray, apiUrl, options);
                    }
                    if (otpResponse.kind === "expected_server") {
                        const error = otpResponse.error;
                        if (emailAndOtpRequired(error)) {
                            return response_Response.badRequest("Invalid email or verification code");
                        }
                    }
                    return this.handleError(otpResponse);
                }
            }
            return this.handleError(emailResponse);
        });
    }
    handlePasswordAuth(sendId, keyArray, apiUrl, options) {
        return receive_command_awaiter(this, void 0, void 0, function* () {
            let password = options.password;
            if (password == null || password === "") {
                if (options.passwordfile) {
                    password = yield NodeUtils.readFirstLine(options.passwordfile);
                }
                else if (options.passwordenv && process.env[options.passwordenv]) {
                    password = process.env[options.passwordenv];
                }
            }
            if ((password == null || password === "") && this.canInteract) {
                const answer = yield external_inquirer_namespaceObject.createPromptModule({ output: process.stderr })({
                    type: "password",
                    name: "password",
                    message: "Send password:",
                });
                password = answer.password;
            }
            if (!password) {
                return response_Response.badRequest("Password required");
            }
            const passwordHashB64 = yield this.getUnlockedPassword(password, keyArray);
            // Use retry helper for expired token handling
            const response = yield this.getTokenWithRetry(sendId, {
                kind: "password",
                passwordHashB64: passwordHashB64,
            });
            if (response instanceof SendAccessToken) {
                return yield this.accessSendWithToken(response, keyArray, apiUrl, options);
            }
            if (response.kind === "expected_server") {
                const error = response.error;
                if (passwordHashB64Invalid(error)) {
                    return response_Response.badRequest("Invalid password");
                }
            }
            else if (response.kind === "unexpected_server") {
                return response_Response.error("Server error: " + JSON.stringify(response.error));
            }
            else if (response.kind === "unknown") {
                return response_Response.error("Error: " + response.error);
            }
            return response_Response.error("Authentication failed");
        });
    }
    accessSendWithToken(accessToken, keyArray, apiUrl, options) {
        return receive_command_awaiter(this, void 0, void 0, function* () {
            var _a, _b, _c;
            try {
                const sendResponse = yield this.sendApiService.postSendAccessV2(accessToken, apiUrl);
                const sendAccess = new SendAccess(sendResponse);
                this.decKey = yield this.keyService.makeSendKey(keyArray);
                const decryptedView = yield sendAccess.decrypt(this.decKey);
                if (options.obj != null) {
                    return response_Response.success(new SendAccessResponse(decryptedView));
                }
                switch (decryptedView.type) {
                    case send_type_SendType.Text:
                        process.stdout.write((_a = decryptedView === null || decryptedView === void 0 ? void 0 : decryptedView.text) === null || _a === void 0 ? void 0 : _a.text);
                        return response_Response.success();
                    case send_type_SendType.File: {
                        const downloadData = yield this.sendApiService.getSendFileDownloadDataV2(decryptedView, accessToken, apiUrl);
                        const decryptBufferFn = (resp) => receive_command_awaiter(this, void 0, void 0, function* () {
                            const encBuf = yield EncArrayBuffer.fromResponse(resp);
                            return this.encryptService.decryptFileData(encBuf, this.decKey);
                        });
                        return yield this.saveAttachmentToFile(downloadData.url, external_path_namespaceObject.basename((_c = (_b = decryptedView === null || decryptedView === void 0 ? void 0 : decryptedView.file) === null || _b === void 0 ? void 0 : _b.fileName) !== null && _c !== void 0 ? _c : `BitwardenSendFile-${Date.now()}`), decryptBufferFn, options.output);
                    }
                    default:
                        return response_Response.success(new SendAccessResponse(decryptedView));
                }
            }
            catch (e) {
                if (e instanceof ErrorResponse) {
                    if (e.statusCode === 404) {
                        return response_Response.notFound();
                    }
                }
                return response_Response.error(e);
            }
        });
    }
    sendRequest(url, id, key) {
        return receive_command_awaiter(this, void 0, void 0, function* () {
            try {
                const sendResponse = yield this.sendApiService.postSendAccess(id, this.sendAccessRequest, url);
                const sendAccess = new SendAccess(sendResponse);
                this.decKey = yield this.keyService.makeSendKey(key);
                return yield sendAccess.decrypt(this.decKey);
            }
            catch (e) {
                if (e instanceof ErrorResponse) {
                    if (e.statusCode === 401) {
                        if (this.canInteract) {
                            const answer = yield external_inquirer_namespaceObject.createPromptModule({
                                output: process.stderr,
                            })({
                                type: "password",
                                name: "password",
                                message: "Send password:",
                            });
                            // reattempt with new password
                            this.sendAccessRequest.password = yield this.getUnlockedPassword(answer.password, key);
                            return yield this.sendRequest(url, id, key);
                        }
                        return response_Response.badRequest("Incorrect or missing password");
                    }
                    else if (e.statusCode === 405) {
                        return response_Response.badRequest("Bad Request");
                    }
                    else if (e.statusCode === 404) {
                        return response_Response.notFound();
                    }
                }
                return response_Response.error(e);
            }
        });
    }
}

;// ./src/tools/send/commands/remove-password.command.ts
var remove_password_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore




class SendRemovePasswordCommand {
    constructor(sendService, sendApiService, environmentService, accountService) {
        this.sendService = sendService;
        this.sendApiService = sendApiService;
        this.environmentService = environmentService;
        this.accountService = accountService;
    }
    run(id) {
        return remove_password_command_awaiter(this, void 0, void 0, function* () {
            try {
                yield this.sendApiService.removePassword(id);
                const updatedSend = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sendService.get$(id));
                const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
                const decSend = yield updatedSend.decrypt(activeUserId);
                const env = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.environmentService.environment$);
                const webVaultUrl = env.getWebVaultUrl();
                const res = new SendResponse(decSend, webVaultUrl);
                return response_Response.success(res);
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
}

;// ./src/tools/send/commands/template.command.ts




class SendTemplateCommand {
    constructor() { }
    run(type) {
        let template;
        let response;
        switch (type) {
            case "send.text":
            case "text":
                template = SendResponse.template(send_type_SendType.Text);
                break;
            case "send.file":
            case "file":
                template = SendResponse.template(send_type_SendType.File);
                break;
            default:
                response = response_Response.badRequest("Unknown template object.");
        }
        if (template) {
            response = response_Response.success(new TemplateResponse(template));
        }
        response !== null && response !== void 0 ? response : (response = response_Response.badRequest("An error occurred while retrieving the template."));
        return response;
    }
}

;// ./src/tools/send/commands/index.ts









;// ./src/tools/send/util.ts
/**
 * Parses email addresses from various input formats and combines them with previously parsed emails.
 *
 * Supports: single email, JSON array, comma-separated, or space-separated lists.
 * Note: Function signature follows Commander.js option parsing pattern.
 *
 * @param input - Email input string in any supported format
 * @param previousInput - Previously parsed email addresses to append to
 * @returns Combined array of email addresses
 * @throws {Error} For invalid JSON, non-array JSON, invalid email addresses, or unrecognized format
 *
 * @example
 * parseEmail("user@example.com", []) // ["user@example.com"]
 * parseEmail('["user1@example.com", "user2@example.com"]', []) // ["user1@example.com", "user2@example.com"]
 * parseEmail("user1@example.com, user2@example.com", []) // ["user1@example.com", "user2@example.com"]
 */
function parseEmail(input, previousInput) {
    let result = previousInput !== null && previousInput !== void 0 ? previousInput : [];
    if (isEmail(input)) {
        result.push(input);
    }
    else if (input.startsWith("[")) {
        const json = JSON.parse(input);
        if (!Array.isArray(json)) {
            throw new Error("invalid JSON");
        }
        result = result.concat(json);
    }
    else if (input.includes(",")) {
        result = result.concat(parseList(input, ","));
    }
    else if (input.includes(" ")) {
        result = result.concat(parseList(input, " "));
    }
    else {
        throw new Error("`input` must be a single address, a comma-separated list, or a JSON array");
    }
    return result;
}
function isEmail(input) {
    return !!input && !!input.match(/^([\w._+-]+?)@([\w._+-]+?)$/);
}
function parseList(value, separator) {
    const parts = value
        .split(separator)
        .map((v) => v.trim())
        .filter((v) => !!v.length);
    const invalid = parts.find((v) => !isEmail(v));
    if (invalid) {
        throw new Error(`Invalid email address: ${invalid}`);
    }
    return parts;
}

;// ./src/tools/send/send.program.ts
var send_program_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore















const send_program_writeLn = CliUtils.writeLn;
class SendProgram extends BaseProgram {
    register() {
        return send_program_awaiter(this, void 0, void 0, function* () {
            const emailAuthEnabled = yield this.serviceContainer.configService.getFeatureFlag(feature_flag_enum_FeatureFlag.SendEmailOTP);
            external_commander_namespaceObject.program.addCommand(this.sendCommand(emailAuthEnabled));
            // receive is accessible both at `bw receive` and `bw send receive`
            external_commander_namespaceObject.program.addCommand(this.receiveCommand());
        });
    }
    sendCommand(emailAuthEnabled) {
        return new external_commander_namespaceObject.Command("send")
            .argument("<data>", "The data to Send. Specify as a filepath with the --file option")
            .description("Work with Bitwarden sends. A Send can be quickly created using this command or subcommands can be used to fine-tune the Send")
            .option("-f, --file", "Specifies that <data> is a filepath")
            .option("-d, --deleteInDays <days>", "The number of days in the future to set deletion date, defaults to 7", "7")
            .addOption(new external_commander_namespaceObject.Option("--password <password>", "optional password to access this Send. Can also be specified in JSON.").conflicts("emails"))
            .addOption(new external_commander_namespaceObject.Option("--emails <emails>", "optional emails to access this Send. Can also be specified in JSON.").argParser(parseEmail))
            .option("-a, --maxAccessCount <amount>", "The amount of max possible accesses.")
            .option("--hidden", "Hide <data> in web by default. Valid only if --file is not set.")
            .option("-n, --name <name>", "The name of the Send. Defaults to a guid for text Sends and the filename for files.")
            .option("--notes <notes>", "Notes to add to the Send.")
            .option("--fullObject", "Specifies that the full Send object should be returned rather than just the access url.")
            .addCommand(this.listCommand())
            .addCommand(this.templateCommand())
            .addCommand(this.getCommand())
            .addCommand(this.receiveCommand())
            .addCommand(this.createCommand(emailAuthEnabled))
            .addCommand(this.editCommand(emailAuthEnabled))
            .addCommand(this.removePasswordCommand())
            .addCommand(this.deleteCommand())
            .action((data, options) => send_program_awaiter(this, void 0, void 0, function* () {
            if (options.emails) {
                if (!emailAuthEnabled) {
                    this.processResponse(response_Response.error("The --emails feature is not currently available."));
                    return;
                }
            }
            const encodedJson = this.makeSendJson(data, options);
            let response;
            if (encodedJson instanceof response_Response) {
                response = encodedJson;
            }
            else {
                response = yield this.runCreate(encodedJson, options);
            }
            this.processResponse(response);
        }));
    }
    receiveCommand() {
        return new external_commander_namespaceObject.Command("receive")
            .arguments("<url>")
            .description("Access a Bitwarden Send from a url")
            .option("--password <password>", "Password needed to access the Send.")
            .option("--passwordenv <passwordenv>", "Environment variable storing the Send's password")
            .option("--passwordfile <passwordfile>", "Path to a file containing the Sends password as its first line")
            .option("--obj", "Return the Send's json object rather than the Send's content")
            .option("--output <location>", "Specify a file path to save a File-type Send to")
            .on("--help", () => {
            send_program_writeLn("");
            send_program_writeLn("If a password is required, the provided password is used or the user is prompted.");
            send_program_writeLn("", true);
        })
            .action((url, options) => send_program_awaiter(this, void 0, void 0, function* () {
            const cmd = new SendReceiveCommand(this.serviceContainer.keyService, this.serviceContainer.encryptService, this.serviceContainer.cryptoFunctionService, this.serviceContainer.platformUtilsService, this.serviceContainer.environmentService, this.serviceContainer.sendApiService, this.serviceContainer.apiService, this.serviceContainer.sendTokenService, this.serviceContainer.configService);
            const response = yield cmd.run(url, options);
            this.processResponse(response);
        }));
    }
    listCommand() {
        return new external_commander_namespaceObject.Command("list")
            .description("List all the Sends owned by you")
            .on("--help", () => {
            send_program_writeLn(external_chalk_namespaceObject("This is in the list command"));
        })
            .action((options) => send_program_awaiter(this, void 0, void 0, function* () {
            yield this.exitIfLocked();
            const cmd = new SendListCommand(this.serviceContainer.sendService, this.serviceContainer.environmentService, this.serviceContainer.searchService, this.serviceContainer.accountService);
            const response = yield cmd.run(options);
            this.processResponse(response);
        }));
    }
    templateCommand() {
        return new external_commander_namespaceObject.Command("template")
            .argument("<object>", "Valid objects are: send.text, text, send.file, file")
            .description("Get json templates for send objects")
            .action((object) => {
            this.processResponse(new SendTemplateCommand().run(object));
        });
    }
    getCommand() {
        return new external_commander_namespaceObject.Command("get")
            .arguments("<id>")
            .description("Get Sends owned by you.")
            .option("--output <output>", "Output directory or filename for attachment.")
            .option("--text", "Specifies to return the text content of a Send")
            .on("--help", () => {
            send_program_writeLn("");
            send_program_writeLn("  Id:");
            send_program_writeLn("");
            send_program_writeLn("    Search term or Send's globally unique `id`.");
            send_program_writeLn("");
            send_program_writeLn("    If raw output is specified and no output filename or directory is given for");
            send_program_writeLn("    an attachment query, the attachment content is written to stdout.");
            send_program_writeLn("");
            send_program_writeLn("  Examples:");
            send_program_writeLn("");
            send_program_writeLn("    bw send get searchText");
            send_program_writeLn("    bw send get id");
            send_program_writeLn("    bw send get searchText --text");
            send_program_writeLn("    bw send get searchText --file");
            send_program_writeLn("    bw send get searchText --file --output ../Photos/photo.jpg");
            send_program_writeLn("    bw send get searchText --file --raw");
            send_program_writeLn("", true);
        })
            .action((id, options) => send_program_awaiter(this, void 0, void 0, function* () {
            yield this.exitIfLocked();
            const cmd = new SendGetCommand(this.serviceContainer.sendService, this.serviceContainer.environmentService, this.serviceContainer.searchService, this.serviceContainer.encryptService, this.serviceContainer.apiService, this.serviceContainer.accountService);
            const response = yield cmd.run(id, options);
            this.processResponse(response);
        }));
    }
    createCommand(emailAuthEnabled) {
        return new external_commander_namespaceObject.Command("create")
            .argument("[encodedJson]", "JSON object to upload. Can also be piped in through stdin.")
            .description("create a Send")
            .option("--file <path>", "file to Send. Can also be specified in parent's JSON.")
            .option("--text <text>", "text to Send. Can also be specified in parent's JSON.")
            .option("--hidden", "text hidden flag. Valid only with the --text option.")
            .on("--help", () => {
            send_program_writeLn("");
            send_program_writeLn("Note:");
            send_program_writeLn("  Options specified in JSON take precedence over command options");
            send_program_writeLn("", true);
        })
            .action((encodedJson, options, args) => send_program_awaiter(this, void 0, void 0, function* () {
            // subcommands inherit flags from their parent; they cannot override them
            const { fullObject = false, emails = undefined, password = undefined } = args.parent.opts();
            if (emails) {
                if (!emailAuthEnabled) {
                    this.processResponse(response_Response.error("The --emails feature is not currently available."));
                    return;
                }
            }
            const mergedOptions = Object.assign(Object.assign({}, options), { fullObject: fullObject, emails,
                password });
            const response = yield this.runCreate(encodedJson, mergedOptions);
            this.processResponse(response);
        }));
    }
    editCommand(emailAuthEnabled) {
        return new external_commander_namespaceObject.Command("edit")
            .argument("[encodedJson]", "Updated JSON object to save. If not provided, encodedJson is read from stdin.")
            .description("edit a Send")
            .option("--itemid <itemid>", "Overrides the itemId provided in [encodedJson]")
            .on("--help", () => {
            send_program_writeLn("");
            send_program_writeLn("Note:");
            send_program_writeLn("  You cannot update a File-type Send's file. Just delete and remake it");
            send_program_writeLn("", true);
        })
            .action((encodedJson, options, args) => send_program_awaiter(this, void 0, void 0, function* () {
            yield this.exitIfLocked();
            const { emails = undefined, password = undefined } = args.parent.opts();
            if (emails) {
                if (!emailAuthEnabled) {
                    this.processResponse(response_Response.error("The --emails feature is not currently available."));
                    return;
                }
            }
            const getCmd = new SendGetCommand(this.serviceContainer.sendService, this.serviceContainer.environmentService, this.serviceContainer.searchService, this.serviceContainer.encryptService, this.serviceContainer.apiService, this.serviceContainer.accountService);
            const cmd = new SendEditCommand(this.serviceContainer.sendService, getCmd, this.serviceContainer.sendApiService, this.serviceContainer.billingAccountProfileStateService, this.serviceContainer.accountService);
            const mergedOptions = Object.assign(Object.assign({}, options), { emails,
                password });
            const response = yield cmd.run(encodedJson, mergedOptions);
            this.processResponse(response);
        }));
    }
    deleteCommand() {
        return new external_commander_namespaceObject.Command("delete")
            .argument("<id>", "The id of the Send to delete.")
            .description("delete a Send")
            .action((id) => send_program_awaiter(this, void 0, void 0, function* () {
            yield this.exitIfLocked();
            const cmd = new SendDeleteCommand(this.serviceContainer.sendService, this.serviceContainer.sendApiService);
            const response = yield cmd.run(id);
            this.processResponse(response);
        }));
    }
    removePasswordCommand() {
        return new external_commander_namespaceObject.Command("remove-password")
            .argument("<id>", "The id of the Send to alter.")
            .description("removes the saved password from a Send.")
            .action((id) => send_program_awaiter(this, void 0, void 0, function* () {
            yield this.exitIfLocked();
            const cmd = new SendRemovePasswordCommand(this.serviceContainer.sendService, this.serviceContainer.sendApiService, this.serviceContainer.environmentService, this.serviceContainer.accountService);
            const response = yield cmd.run(id);
            this.processResponse(response);
        }));
    }
    makeSendJson(data, options) {
        var _a, _b;
        let sendFile = null;
        let sendText = null;
        let name = utils_Utils.newGuid();
        let type = send_type_SendType.Text;
        if (options.file != null) {
            data = external_path_namespaceObject.resolve(data);
            if (!external_fs_namespaceObject.existsSync(data)) {
                return response_Response.badRequest("data path does not exist");
            }
            sendFile = SendFileResponse.template(data);
            name = external_path_namespaceObject.basename(data);
            type = send_type_SendType.File;
        }
        else {
            sendText = SendTextResponse.template(data, options.hidden);
        }
        const template = utils_Utils.assign(SendResponse.template(null, options.deleteInDays), {
            name: (_a = options.name) !== null && _a !== void 0 ? _a : name,
            notes: options.notes,
            file: sendFile,
            text: sendText,
            type: type,
            emails: (_b = options.emails) !== null && _b !== void 0 ? _b : undefined,
        });
        return Buffer.from(JSON.stringify(template), "utf8").toString("base64");
    }
    runCreate(encodedJson, options) {
        return send_program_awaiter(this, void 0, void 0, function* () {
            yield this.exitIfLocked();
            const cmd = new SendCreateCommand(this.serviceContainer.sendService, this.serviceContainer.environmentService, this.serviceContainer.sendApiService, this.serviceContainer.billingAccountProfileStateService, this.serviceContainer.accountService);
            return yield cmd.run(encodedJson, options);
        });
    }
}

;// ../../libs/admin-console/src/common/collections/models/collection.request.ts
class collection_request_BaseCollectionRequest {
    constructor(c) {
        this.groups = [];
        this.users = [];
        this.externalId = c.externalId;
        if (c.groups) {
            this.groups = c.groups;
        }
        if (c.users) {
            this.users = c.users;
        }
    }
}
collection_request_BaseCollectionRequest.isUpdate = (request) => {
    return request instanceof collection_request_UpdateCollectionRequest;
};
class collection_request_CreateCollectionRequest extends collection_request_BaseCollectionRequest {
    constructor(c) {
        super(c);
        if (!c.name || !c.name.encryptedString) {
            throw new Error("Name not provided for CollectionRequest.");
        }
        this.name = c.name.encryptedString;
    }
}
class collection_request_UpdateCollectionRequest extends collection_request_BaseCollectionRequest {
    constructor(c) {
        var _a, _b;
        super(c);
        this.name = (_b = (_a = c.name) === null || _a === void 0 ? void 0 : _a.encryptedString) !== null && _b !== void 0 ? _b : null;
    }
}

;// ../../libs/admin-console/src/common/collections/models/collection-with-id.request.ts

class CollectionWithIdRequest extends collection_request_BaseCollectionRequest {
    constructor(collection) {
        if (collection == null || collection.name == null || collection.name.encryptedString == null) {
            throw new Error("CollectionWithIdRequest must contain name.");
        }
        super({
            externalId: collection.externalId,
        });
        this.name = collection.name.encryptedString;
        this.id = collection.id;
    }
}

;// ../../libs/admin-console/src/common/collections/models/index.ts




;// ../../libs/common/src/admin-console/abstractions/organization/organization.service.abstraction.ts


function canAccessVaultTab(org) {
    return org.canViewAllCollections;
}
function canAccessSettingsTab(org) {
    return (org.isOwner ||
        org.canManagePolicies ||
        org.canManageSso ||
        org.canManageScim ||
        org.canAccessImport ||
        org.canAccessExport ||
        org.canManageDeviceApprovals);
}
function canAccessMembersTab(org) {
    return org.canManageUsers || org.canManageUsersPassword;
}
function canAccessGroupsTab(org) {
    return org.canManageGroups;
}
function canAccessReportingTab(org) {
    return org.canAccessReports || org.canAccessEventLogs;
}
function canAccessBillingTab(org) {
    return org.isOwner;
}
/**
 * Access Intelligence is only available to:
 * - Enterprise organizations
 * - Users in those organizations with report access
 *
 * @param org The organization to verify access
 * @returns If true can access the Access Intelligence feature
 */
function canAccessAccessIntelligence(org) {
    return org.canUseAccessIntelligence && org.canAccessReports;
}
function canAccessOrgAdmin(org) {
    // Admin console can only be accessed by Owners for disabled organizations
    if (!org.enabled && !org.isOwner) {
        return false;
    }
    return (canAccessMembersTab(org) ||
        canAccessGroupsTab(org) ||
        canAccessReportingTab(org) ||
        canAccessBillingTab(org) ||
        canAccessSettingsTab(org) ||
        canAccessVaultTab(org));
}
function canAccessEmergencyAccess(userId, policyService) {
    return policyService
        .policyAppliesToUser$(PolicyType.AutoConfirm, userId)
        .pipe(map((policyAppliesToUser) => !policyAppliesToUser));
}
/**
 * @deprecated Please use the general `getById` custom rxjs operator instead.
 */
function organization_service_abstraction_getOrganizationById(id) {
    return (0,external_rxjs_namespaceObject.map)((orgs) => orgs.find((o) => o.id === id));
}
/**
 * Publishes an observable stream of organizations. This service is meant to
 * be used widely across Bitwarden as the primary way of fetching organizations.
 * Risky operations like updates are isolated to the
 * internal extension `InternalOrganizationServiceAbstraction`.
 */
class OrganizationService {
}
/**
 * Big scary buttons that **update** organization state. These should only be
 * called from within admin-console scoped code. Extends the base
 * `OrganizationService` for easy access to `get` calls.
 * @internal
 */
class InternalOrganizationServiceAbstraction extends (/* unused pure expression or super */ null && (OrganizationService)) {
}

;// ../../libs/common/src/models/view/view.ts
// See https://contributing.bitwarden.com/architecture/clients/data-model/#view for proper use.
// View models represent the decrypted state of a corresponding Domain model.
// They typically match the Domain model but contains a decrypted string for any EncString fields.
// Don't use this to represent arbitrary component view data as that isn't what it is for.
class View {
}

;// ../../libs/common/src/admin-console/models/collections/collection-access-selection.view.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

class CollectionAccessSelectionView extends View {
    constructor(response) {
        super();
        if (!response) {
            return;
        }
        this.id = response.id;
        this.readOnly = response.readOnly;
        this.hidePasswords = response.hidePasswords;
        this.manage = response.manage;
    }
}

;// ../../libs/common/src/admin-console/models/collections/collection.ts
var collection_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};



const CollectionTypes = {
    SharedCollection: 0,
    DefaultUserCollection: 1,
};
class Collection extends Domain {
    constructor(c) {
        super();
        this.readOnly = false;
        this.hidePasswords = false;
        this.manage = false;
        this.type = CollectionTypes.SharedCollection;
        this.id = c.id;
        this.name = c.name;
        this.organizationId = c.organizationId;
    }
    static fromCollectionData(obj) {
        if (obj == null || obj.name == null || obj.organizationId == null) {
            throw new Error("CollectionData must contain name and organizationId.");
        }
        const collection = new Collection(Object.assign(Object.assign({}, obj), { name: new enc_string_EncString(obj.name) }));
        collection.externalId = obj.externalId;
        collection.readOnly = obj.readOnly;
        collection.hidePasswords = obj.hidePasswords;
        collection.manage = obj.manage;
        collection.type = obj.type;
        collection.defaultUserCollectionEmail = obj.defaultUserCollectionEmail;
        return collection;
    }
    static fromCollectionView(view, encryptService, orgKey) {
        return collection_awaiter(this, void 0, void 0, function* () {
            const collection = new Collection({
                name: yield encryptService.encryptString(view.name, orgKey),
                id: view.id,
                organizationId: view.organizationId,
            });
            collection.externalId = view.externalId;
            collection.readOnly = view.readOnly;
            collection.hidePasswords = view.hidePasswords;
            collection.manage = view.manage;
            collection.type = view.type;
            return collection;
        });
    }
    decrypt(orgKey, encryptService) {
        return CollectionView.fromCollection(this, encryptService, orgKey);
    }
    // @TODO: This would be better off in Collection.Utils. Move this there when
    // refactoring to a shared lib.
    static isCollectionId(id) {
        return typeof id === "string" && id != null;
    }
}

;// ../../libs/common/src/admin-console/models/collections/collection.view.ts
var collection_view_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};


const NestingDelimiter = "/";
class CollectionView {
    constructor(c) {
        // readOnly applies to the items within a collection
        this.readOnly = false;
        this.hidePasswords = false;
        this.manage = false;
        this.assigned = false;
        this.type = CollectionTypes.SharedCollection;
        this.id = c.id;
        this.organizationId = c.organizationId;
        this._name = c.name;
    }
    set name(name) {
        this._name = name;
    }
    get name() {
        var _a;
        return (_a = this.defaultUserCollectionEmail) !== null && _a !== void 0 ? _a : this._name;
    }
    canEditItems(org) {
        if (org != null && org.id !== this.organizationId) {
            throw new Error("Id of the organization provided does not match the org id of the collection.");
        }
        return (org === null || org === void 0 ? void 0 : org.canEditAllCiphers) || this.manage || (this.assigned && !this.readOnly);
    }
    /**
     * Returns true if the user can edit a collection (including user and group access) from the individual vault.
     * Does not include admin permissions - see {@link CollectionAdminView.canEdit}.
     */
    canEdit(org) {
        if (this.isDefaultCollection) {
            return false;
        }
        if (org != null && org.id !== this.organizationId) {
            throw new Error("Id of the organization provided does not match the org id of the collection.");
        }
        return this.manage;
    }
    /**
     * Returns true if the user can delete a collection from the individual vault.
     * Does not include admin permissions - see {@link CollectionAdminView.canDelete}.
     */
    canDelete(org) {
        if (org != null && org.id !== this.organizationId) {
            throw new Error("Id of the organization provided does not match the org id of the collection.");
        }
        const canDeleteManagedCollections = !(org === null || org === void 0 ? void 0 : org.limitCollectionDeletion) || org.isAdmin;
        // Only use individual permissions, not admin permissions
        return canDeleteManagedCollections && this.manage && !this.isDefaultCollection;
    }
    /**
     * Returns true if the user can view collection info and access in a read-only state from the individual vault
     */
    canViewCollectionInfo(org) {
        return false;
    }
    /**
     * Returns true if the collection name can be edited. Editing the collection name is restricted for collections
     * that were DefaultUserCollections but where the relevant user has been offboarded.
     * When this occurs, the offboarded user's email is treated as the collection name, and cannot be edited.
     * This is important for security so that the server cannot ask the client to encrypt arbitrary data.
     * WARNING! This is an IMPORTANT restriction that MUST be maintained for security purposes.
     * Do not edit or remove this unless you understand why.
     */
    canEditName(org) {
        return this.canEdit(org) && !this.defaultUserCollectionEmail;
    }
    get isDefaultCollection() {
        return this.type == CollectionTypes.DefaultUserCollection;
    }
    // FIXME: we should not use a CollectionView object for the vault filter header because it is not a real
    // CollectionView and this violates ts-strict rules.
    static vaultFilterHead() {
        return new CollectionView({
            id: "",
            organizationId: "",
            name: "",
        });
    }
    static fromCollection(collection, encryptService, key) {
        return collection_view_awaiter(this, void 0, void 0, function* () {
            const view = new CollectionView(Object.assign(Object.assign({}, collection), { name: "" }));
            try {
                view.name = yield encryptService.decryptString(collection.name, key);
            }
            catch (e) {
                view.name = "[error: cannot decrypt]";
                // eslint-disable-next-line no-console
                console.error("[CollectionView] Error decrypting collection name", e);
            }
            view.assigned = true;
            view.externalId = collection.externalId;
            view.readOnly = collection.readOnly;
            view.hidePasswords = collection.hidePasswords;
            view.manage = collection.manage;
            view.type = collection.type;
            view.defaultUserCollectionEmail = collection.defaultUserCollectionEmail;
            return view;
        });
    }
    static fromCollectionAccessDetails(collection, encryptService, orgKey) {
        return collection_view_awaiter(this, void 0, void 0, function* () {
            const view = new CollectionView(Object.assign({}, collection));
            try {
                view.name = yield encryptService.decryptString(new enc_string_EncString(collection.name), orgKey);
            }
            catch (e) {
                // Note: This should be replaced by the owning team with appropriate, domain-specific behavior.
                // eslint-disable-next-line no-console
                console.error("[CollectionView] Error decrypting collection name", e);
                throw e;
            }
            view.externalId = collection.externalId;
            view.type = collection.type;
            view.assigned = collection.assigned;
            view.defaultUserCollectionEmail = collection.defaultUserCollectionEmail;
            return view;
        });
    }
    static fromJSON(obj) {
        return Object.assign(new CollectionView(Object.assign({}, obj)), obj);
    }
    encrypt(orgKey, encryptService) {
        return Collection.fromCollectionView(this, encryptService, orgKey);
    }
}

;// ../../libs/common/src/admin-console/models/collections/collection-admin.view.ts
var collection_admin_view_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};



// TODO: this is used to represent the pseudo "Unassigned" collection as well as
// the user's personal vault (as a pseudo organization). This should be separated out into different values.
const Unassigned = "unassigned";
class collection_admin_view_CollectionAdminView extends CollectionView {
    constructor() {
        super(...arguments);
        this.groups = [];
        this.users = [];
        /**
         * Flag indicating the collection has no active user or group assigned to it with CanManage permissions
         * In this case, the collection can be managed by admins/owners or custom users with appropriate permissions
         */
        this.unmanaged = false;
        /**
         * Flag indicating the user has been explicitly assigned to this Collection
         */
        this.assigned = false;
    }
    /**
     * Returns true if the user can edit a collection (including user and group access) from the Admin Console.
     */
    canEdit(org) {
        if (this.isDefaultCollection) {
            return false;
        }
        return ((org === null || org === void 0 ? void 0 : org.canEditAnyCollection) ||
            (this.unmanaged && (org === null || org === void 0 ? void 0 : org.canEditUnmanagedCollections)) ||
            super.canEdit(org));
    }
    /**
     * Returns true if the user can delete a collection from the Admin Console.
     */
    canDelete(org) {
        if (this.isDefaultCollection) {
            return false;
        }
        return (org === null || org === void 0 ? void 0 : org.canDeleteAnyCollection) || super.canDelete(org);
    }
    /**
     * Whether the user can modify user access to this collection
     */
    canEditUserAccess(org) {
        if (this.isDefaultCollection) {
            return false;
        }
        return ((org.permissions.manageUsers && org.allowAdminAccessToAllCollectionItems) || this.canEdit(org));
    }
    /**
     * Whether the user can modify group access to this collection
     */
    canEditGroupAccess(org) {
        if (this.isDefaultCollection) {
            return false;
        }
        return ((org.permissions.manageGroups && org.allowAdminAccessToAllCollectionItems) ||
            this.canEdit(org));
    }
    /**
     * Returns true if the user can view collection info and access in a read-only state from the Admin Console
     */
    canViewCollectionInfo(org) {
        var _a, _b;
        if (this.isUnassignedCollection || this.isDefaultCollection) {
            return false;
        }
        const isAdmin = (_a = org === null || org === void 0 ? void 0 : org.isAdmin) !== null && _a !== void 0 ? _a : false;
        const permissions = (_b = org === null || org === void 0 ? void 0 : org.permissions.editAnyCollection) !== null && _b !== void 0 ? _b : false;
        return this.manage || isAdmin || permissions;
    }
    /**
     * True if this collection represents the pseudo "Unassigned" collection
     * This is different from the "unmanaged" flag, which indicates that no users or groups have access to the collection
     */
    get isUnassignedCollection() {
        return this.id === Unassigned;
    }
    /**
     * Returns true if the collection name can be edited. Editing the collection name is restricted for collections
     * that were DefaultUserCollections but where the relevant user has been offboarded.
     * When this occurs, the offboarded user's email is treated as the collection name, and cannot be edited.
     * This is important for security so that the server cannot ask the client to encrypt arbitrary data.
     * WARNING! This is an IMPORTANT restriction that MUST be maintained for security purposes.
     * Do not edit or remove this unless you understand why.
     */
    canEditName(org) {
        return (this.canEdit(org) && !this.defaultUserCollectionEmail) || super.canEditName(org);
    }
    static fromCollectionAccessDetails(collection, encryptService, orgKey) {
        return collection_admin_view_awaiter(this, void 0, void 0, function* () {
            const view = new collection_admin_view_CollectionAdminView(Object.assign({}, collection));
            try {
                view.name = yield encryptService.decryptString(new enc_string_EncString(view.name), orgKey);
            }
            catch (e) {
                view.name = "[error: cannot decrypt]";
                // Note: This should be replaced by the owning team with appropriate, domain-specific behavior.
                // eslint-disable-next-line no-console
                console.error("[CollectionAdminView/fromCollectionAccessDetails] Error decrypting collection name", e);
            }
            view.assigned = collection.assigned;
            view.readOnly = collection.readOnly;
            view.hidePasswords = collection.hidePasswords;
            view.manage = collection.manage;
            view.unmanaged = collection.unmanaged;
            view.type = collection.type;
            view.externalId = collection.externalId;
            view.defaultUserCollectionEmail = collection.defaultUserCollectionEmail;
            view.groups = collection.groups
                ? collection.groups.map((g) => new CollectionAccessSelectionView(g))
                : [];
            view.users = collection.users
                ? collection.users.map((g) => new CollectionAccessSelectionView(g))
                : [];
            return view;
        });
    }
    static fromCollectionResponse(collection, encryptService, orgKey) {
        return collection_admin_view_awaiter(this, void 0, void 0, function* () {
            let collectionName;
            try {
                collectionName = yield encryptService.decryptString(new enc_string_EncString(collection.name), orgKey);
            }
            catch (e) {
                // Note: This should be updated by the owning team with appropriate, domain specific behavior
                // eslint-disable-next-line no-console
                console.error("[CollectionAdminView/fromCollectionResponse] Failed to decrypt the collection name", e);
                throw e;
            }
            const collectionAdminView = new collection_admin_view_CollectionAdminView({
                id: collection.id,
                name: collectionName,
                organizationId: collection.organizationId,
            });
            collectionAdminView.externalId = collection.externalId;
            return collectionAdminView;
        });
    }
}

;// ../../libs/common/src/admin-console/models/response/selection-read-only.response.ts

class SelectionReadOnlyResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.id = this.getResponseProperty("Id");
        this.readOnly = this.getResponseProperty("ReadOnly");
        this.hidePasswords = this.getResponseProperty("HidePasswords");
        this.manage = this.getResponseProperty("Manage");
    }
}

;// ../../libs/common/src/admin-console/models/collections/collection.response.ts



class CollectionResponse extends BaseResponse {
    constructor(response) {
        var _a;
        super(response);
        this.type = CollectionTypes.SharedCollection;
        this.id = this.getResponseProperty("Id");
        this.organizationId = this.getResponseProperty("OrganizationId");
        this.name = this.getResponseProperty("Name");
        this.externalId = this.getResponseProperty("ExternalId");
        this.defaultUserCollectionEmail = this.getResponseProperty("DefaultUserCollectionEmail");
        this.type = (_a = this.getResponseProperty("Type")) !== null && _a !== void 0 ? _a : CollectionTypes.SharedCollection;
    }
}
class CollectionDetailsResponse extends CollectionResponse {
    constructor(response) {
        super(response);
        this.readOnly = this.getResponseProperty("ReadOnly") || false;
        this.manage = this.getResponseProperty("Manage") || false;
        this.hidePasswords = this.getResponseProperty("HidePasswords") || false;
        // Temporary until the API is updated to return this property in AC-2084
        // For now, we can assume that if the object is 'collectionDetails' then the user is assigned
        this.assigned = this.getResponseProperty("object") == "collectionDetails";
    }
}
class CollectionAccessDetailsResponse extends CollectionDetailsResponse {
    constructor(response) {
        super(response);
        this.groups = [];
        this.users = [];
        this.assigned = this.getResponseProperty("Assigned") || false;
        this.unmanaged = this.getResponseProperty("Unmanaged") || false;
        const groups = this.getResponseProperty("Groups");
        if (groups != null) {
            this.groups = groups.map((g) => new SelectionReadOnlyResponse(g));
        }
        const users = this.getResponseProperty("Users");
        if (users != null) {
            this.users = users.map((g) => new SelectionReadOnlyResponse(g));
        }
    }
}

;// ../../libs/common/src/admin-console/models/collections/collection.data.ts

class collection_data_CollectionData {
    constructor(response) {
        this.readOnly = false;
        this.manage = false;
        this.hidePasswords = false;
        this.type = CollectionTypes.SharedCollection;
        this.id = response.id;
        this.organizationId = response.organizationId;
        this.name = response.name;
        this.externalId = response.externalId;
        this.readOnly = response.readOnly;
        this.manage = response.manage;
        this.hidePasswords = response.hidePasswords;
        this.type = response.type;
        this.defaultUserCollectionEmail = response.defaultUserCollectionEmail;
    }
    static fromJSON(obj) {
        if (obj == null) {
            return null;
        }
        return Object.assign(new collection_data_CollectionData(new CollectionDetailsResponse({})), obj);
    }
}

;// ../../libs/common/src/admin-console/models/collections/index.ts







;// ../../libs/admin-console/src/common/collections/services/default-collection-admin.service.ts
var default_collection_admin_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};





class DefaultCollectionAdminService {
    constructor(apiService, keyService, encryptService, collectionService, organizationService) {
        this.apiService = apiService;
        this.keyService = keyService;
        this.encryptService = encryptService;
        this.collectionService = collectionService;
        this.organizationService = organizationService;
    }
    collectionAdminViews$(organizationId, userId) {
        return combineLatest([
            this.keyService.orgKeys$(userId),
            from(this.apiService.getManyCollectionsWithAccessDetails(organizationId)),
        ]).pipe(switchMap(([orgKeys, res]) => {
            if ((res === null || res === void 0 ? void 0 : res.data) == null || res.data.length === 0) {
                return of([]);
            }
            if (orgKeys == null) {
                throw new Error("No org keys found.");
            }
            return this.decryptMany(organizationId, res.data, orgKeys);
        }));
    }
    update(collection, userId) {
        return default_collection_admin_service_awaiter(this, void 0, void 0, function* () {
            const request = yield this.encrypt(collection, userId, true);
            if (!BaseCollectionRequest.isUpdate(request)) {
                throw new Error("Cannot update collection with CreateCollectionRequest.");
            }
            const response = yield this.apiService.putCollection(collection.organizationId, collection.id, request);
            yield this.updateLocalCollections(response, collection, userId);
            return response;
        });
    }
    create(collection, userId) {
        return default_collection_admin_service_awaiter(this, void 0, void 0, function* () {
            const request = yield this.encrypt(collection, userId, false);
            if (BaseCollectionRequest.isUpdate(request)) {
                throw new Error("Cannot create collection with UpdateCollectionRequest.");
            }
            const response = yield this.apiService.postCollection(collection.organizationId, request);
            collection.id = response.id;
            yield this.updateLocalCollections(response, collection, userId);
            return response;
        });
    }
    delete(organizationId, collectionId) {
        return default_collection_admin_service_awaiter(this, void 0, void 0, function* () {
            yield this.apiService.deleteCollection(organizationId, collectionId);
        });
    }
    updateLocalCollections(response, collection, userId) {
        return default_collection_admin_service_awaiter(this, void 0, void 0, function* () {
            response.assigned
                ? yield this.collectionService.upsert(new CollectionData(response), userId)
                : yield this.collectionService.delete([collection.id], userId);
        });
    }
    bulkAssignAccess(organizationId, collectionIds, users, groups) {
        return default_collection_admin_service_awaiter(this, void 0, void 0, function* () {
            const request = new BulkCollectionAccessRequest();
            request.collectionIds = collectionIds;
            request.users = users.map((u) => new SelectionReadOnlyRequest(u.id, u.readOnly, u.hidePasswords, u.manage));
            request.groups = groups.map((g) => new SelectionReadOnlyRequest(g.id, g.readOnly, g.hidePasswords, g.manage));
            yield this.apiService.send("POST", `/organizations/${organizationId}/collections/bulk-access`, request, true, false);
        });
    }
    decryptMany(organizationId, collections, orgKeys) {
        return default_collection_admin_service_awaiter(this, void 0, void 0, function* () {
            const promises = collections.map((c) => default_collection_admin_service_awaiter(this, void 0, void 0, function* () {
                if (isCollectionAccessDetailsResponse(c)) {
                    return CollectionAdminView.fromCollectionAccessDetails(c, this.encryptService, orgKeys[organizationId]);
                }
                return yield CollectionAdminView.fromCollectionResponse(c, this.encryptService, orgKeys[organizationId]);
            }));
            const r = yield Promise.all(promises);
            return r;
        });
    }
    encrypt(model, userId, editMode) {
        return default_collection_admin_service_awaiter(this, void 0, void 0, function* () {
            if (!model.organizationId) {
                throw new Error("Collection has no organization id.");
            }
            const key = yield firstValueFrom(this.keyService.orgKeys$(userId).pipe(map((orgKeys) => {
                if (!orgKeys) {
                    throw new Error("No keys for the provided userId.");
                }
                const key = orgKeys[model.organizationId];
                if (key == null) {
                    throw new Error("No key for this collection's organization.");
                }
                return key;
            })));
            const groups = model.groups.map((group) => new SelectionReadOnlyRequest(group.id, group.readOnly, group.hidePasswords, group.manage));
            const users = model.users.map((user) => new SelectionReadOnlyRequest(user.id, user.readOnly, user.hidePasswords, user.manage));
            if (editMode) {
                const org = yield firstValueFrom(this.organizationService
                    .organizations$(userId)
                    .pipe(getOrganizationById(model.organizationId)));
                if (org == null) {
                    throw new Error("No Organization found.");
                }
                return new UpdateCollectionRequest({
                    name: model.canEditName(org)
                        ? yield this.encryptService.encryptString(model.name, key)
                        : null,
                    externalId: model.externalId,
                    users,
                    groups,
                });
            }
            return new CreateCollectionRequest({
                name: yield this.encryptService.encryptString(model.name, key),
                externalId: model.externalId,
                users,
                groups,
            });
        });
    }
}
function isCollectionAccessDetailsResponse(response) {
    const anyResponse = response;
    return (anyResponse === null || anyResponse === void 0 ? void 0 : anyResponse.groups) instanceof Array && (anyResponse === null || anyResponse === void 0 ? void 0 : anyResponse.users) instanceof Array;
}

;// ../../libs/common/src/vault/models/domain/tree-node.ts
class TreeNode {
    constructor(node, parent, name, id) {
        this.children = [];
        this.parent = parent;
        this.node = node;
        if (name) {
            this.node.name = name;
        }
        if (id) {
            this.node.id = id;
        }
    }
}

;// ../../libs/common/src/vault/service-utils.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

class ServiceUtils {
    /**
     * Recursively adds a node to nodeTree
     * @param {TreeNode<ITreeNodeObject>[]} nodeTree - An array of TreeNodes that the node will be added to
     * @param {number} partIndex - Index of the `parts` array that is being processed
     * @param {string[]} parts - Array of strings that represent the path to the `obj` node
     * @param {ITreeNodeObject} obj - The node to be added to the tree
     * @param {ITreeNodeObject} parent - The parent node of the `obj` node
     * @param {string} delimiter - The delimiter used to split the path string, will be used to combine the path for missing nodes
     */
    static nestedTraverse(nodeTree, partIndex, parts, obj, parent, delimiter) {
        if (parts.length <= partIndex) {
            return;
        }
        // 'end' indicates we've traversed as far as we can based on the object name
        const end = partIndex === parts.length - 1;
        const partName = parts[partIndex];
        // If we're at the end, just add the node - it doesn't matter what else is here
        if (end) {
            nodeTree.push(new TreeNode(obj, parent, partName));
            return;
        }
        // Get matching nodes at this level by name
        // NOTE: this is effectively a loop so we only want to do it once
        const matchingNodes = nodeTree.filter((n) => n.node.name === partName);
        // If there are no matching nodes...
        if (matchingNodes.length === 0) {
            // And we're not at the end of the path (because we didn't trigger the early return above),
            // combine the current name with the next name.
            // 1, *1.2, 1.2.1 becomes
            // 1, *1.2/1.2.1
            const newPartName = partName + delimiter + parts[partIndex + 1];
            ServiceUtils.nestedTraverse(nodeTree, 0, [newPartName, ...parts.slice(partIndex + 2)], obj, parent, delimiter);
        }
        else {
            // There is a node here with the same name, descend into it
            ServiceUtils.nestedTraverse(matchingNodes[0].children, partIndex + 1, parts, obj, matchingNodes[0], delimiter);
            return;
        }
    }
    /**
     * Searches a tree for a node with a matching `id`
     * @param {TreeNode<T extends ITreeNodeObject>} nodeTree - A single TreeNode branch that will be searched
     * @param {string} id - The id of the node to be found
     * @returns {TreeNode<T extends ITreeNodeObject>} The node with a matching `id`
     */
    static getTreeNodeObject(nodeTree, id) {
        if (nodeTree.node.id === id) {
            return nodeTree;
        }
        for (let i = 0; i < nodeTree.children.length; i++) {
            if (nodeTree.children[i].children != null) {
                const node = ServiceUtils.getTreeNodeObject(nodeTree.children[i], id);
                if (node !== null) {
                    return node;
                }
            }
        }
        return null;
    }
    /**
     * Searches an array of tree nodes for a node with a matching `id`
     * @param {TreeNode<T extends ITreeNodeObject>} nodeTree - An array of TreeNode branches that will be searched
     * @param {string} id - The id of the node to be found
     * @returns {TreeNode<T extends ITreeNodeObject>} The node with a matching `id`
     */
    static getTreeNodeObjectFromList(nodeTree, id) {
        for (let i = 0; i < nodeTree.length; i++) {
            if (nodeTree[i].node.id === id) {
                return nodeTree[i];
            }
            else if (nodeTree[i].children != null) {
                const node = ServiceUtils.getTreeNodeObjectFromList(nodeTree[i].children, id);
                if (node !== null) {
                    return node;
                }
            }
        }
        return null;
    }
}

;// ../../libs/admin-console/src/common/collections/services/collection.state.ts


const ENCRYPTED_COLLECTION_DATA_KEY = UserKeyDefinition.record(COLLECTION_DISK, "collections", {
    deserializer: (jsonData) => collection_data_CollectionData.fromJSON(jsonData),
    clearOn: ["logout"],
});
const DECRYPTED_COLLECTION_DATA_KEY = new UserKeyDefinition(COLLECTION_MEMORY, "decryptedCollections", {
    deserializer: (obj) => { var _a; return (_a = obj === null || obj === void 0 ? void 0 : obj.map((f) => CollectionView.fromJSON(f))) !== null && _a !== void 0 ? _a : null; },
    clearOn: ["logout", "lock"],
});

;// ../../libs/admin-console/src/common/collections/services/default-collection.service.ts
var default_collection_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};





const default_collection_service_NestingDelimiter = "/";
class DefaultCollectionService {
    constructor(keyService, encryptService, i18nService, stateProvider) {
        this.keyService = keyService;
        this.encryptService = encryptService;
        this.i18nService = i18nService;
        this.stateProvider = stateProvider;
        this.collectionViewCache = new Map();
    }
    /**
     * @returns a SingleUserState for encrypted collection data.
     */
    encryptedState(userId) {
        return this.stateProvider.getUser(userId, ENCRYPTED_COLLECTION_DATA_KEY);
    }
    /**
     * @returns a SingleUserState for decrypted collection data.
     */
    decryptedState(userId) {
        return this.stateProvider.getUser(userId, DECRYPTED_COLLECTION_DATA_KEY);
    }
    encryptedCollections$(userId) {
        return this.encryptedState(userId).state$.pipe((0,external_rxjs_namespaceObject.map)((collections) => {
            if (collections == null) {
                return null;
            }
            return Object.values(collections).map((c) => Collection.fromCollectionData(c));
        }));
    }
    decryptedCollections$(userId) {
        const cachedResult = this.collectionViewCache.get(userId);
        if (cachedResult) {
            return cachedResult;
        }
        const result$ = this.decryptedState(userId).state$.pipe((0,external_rxjs_namespaceObject.switchMap)((decryptedState) => {
            // If decrypted state is already populated, return that
            if (decryptedState !== null) {
                return (0,external_rxjs_namespaceObject.of)(decryptedState !== null && decryptedState !== void 0 ? decryptedState : []);
            }
            return this.initializeDecryptedState(userId).pipe((0,external_rxjs_namespaceObject.switchMap)(() => external_rxjs_namespaceObject.NEVER));
        }), (0,external_rxjs_namespaceObject.shareReplay)({ bufferSize: 1, refCount: true }));
        this.collectionViewCache.set(userId, result$);
        return result$;
    }
    defaultUserCollection$(userId, orgId) {
        return this.decryptedCollections$(userId).pipe((0,external_rxjs_namespaceObject.map)((collections) => {
            return collections.find((c) => c.isDefaultCollection && c.organizationId === orgId);
        }));
    }
    initializeDecryptedState(userId) {
        return (0,external_rxjs_namespaceObject.combineLatest)([
            this.encryptedCollections$(userId),
            this.keyService.orgKeys$(userId).pipe((0,external_rxjs_namespaceObject.filter)((orgKeys) => !!orgKeys)),
        ]).pipe((0,external_rxjs_namespaceObject.switchMap)(([collections, orgKeys]) => this.decryptMany$(collections, orgKeys).pipe((0,external_rxjs_namespaceObject.delayWhen)((collections) => this.setDecryptedCollections(collections, userId)))));
    }
    upsert(toUpdate, userId) {
        return default_collection_service_awaiter(this, void 0, void 0, function* () {
            if (toUpdate == null) {
                return;
            }
            yield this.encryptedState(userId).update((collections) => {
                if (collections == null) {
                    collections = {};
                }
                collections[toUpdate.id] = toUpdate;
                return collections;
            });
            const decryptedCollections = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.orgKeys$(userId).pipe((0,external_rxjs_namespaceObject.switchMap)((orgKeys) => {
                if (!orgKeys) {
                    throw new Error("No key for this collection's organization.");
                }
                return this.decryptMany$([Collection.fromCollectionData(toUpdate)], orgKeys);
            })));
            yield this.decryptedState(userId).update((collections) => {
                if (collections == null) {
                    collections = [];
                }
                if (!(decryptedCollections === null || decryptedCollections === void 0 ? void 0 : decryptedCollections.length)) {
                    return collections;
                }
                const decryptedCollection = decryptedCollections[0];
                const existingIndex = collections.findIndex((collection) => collection.id == toUpdate.id);
                if (existingIndex >= 0) {
                    collections[existingIndex] = decryptedCollection;
                }
                else {
                    collections.push(decryptedCollection);
                }
                return collections;
            });
        });
    }
    replace(collections, userId) {
        return default_collection_service_awaiter(this, void 0, void 0, function* () {
            yield this.encryptedState(userId).update(() => collections);
            yield this.decryptedState(userId).update(() => null);
        });
    }
    delete(ids, userId) {
        return default_collection_service_awaiter(this, void 0, void 0, function* () {
            yield this.encryptedState(userId).update((collections) => {
                if (collections == null) {
                    collections = {};
                }
                ids.forEach((i) => {
                    delete collections[i];
                });
                return collections;
            });
            yield this.decryptedState(userId).update((collections) => {
                if (collections == null) {
                    collections = [];
                }
                ids.forEach((i) => {
                    var _a;
                    if (collections === null || collections === void 0 ? void 0 : collections.length) {
                        collections = (_a = collections.filter((c) => c.id != i)) !== null && _a !== void 0 ? _a : [];
                    }
                });
                return collections;
            });
        });
    }
    encrypt(model, userId) {
        return default_collection_service_awaiter(this, void 0, void 0, function* () {
            const key = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.orgKeys$(userId).pipe((0,external_rxjs_namespaceObject.filter)((orgKeys) => !!orgKeys), (0,external_rxjs_namespaceObject.map)((k) => k[model.organizationId])));
            return yield model.encrypt(key, this.encryptService);
        });
    }
    // TODO: this should be private.
    // See https://bitwarden.atlassian.net/browse/PM-12375
    decryptMany$(collections, orgKeys) {
        if (collections === null || collections.length == 0 || orgKeys === null) {
            return (0,external_rxjs_namespaceObject.of)([]);
        }
        const decCollections = [];
        collections.forEach((collection) => {
            decCollections.push((0,external_rxjs_namespaceObject.from)(collection.decrypt(orgKeys[collection.organizationId], this.encryptService)));
        });
        return (0,external_rxjs_namespaceObject.combineLatest)(decCollections).pipe((0,external_rxjs_namespaceObject.map)((collections) => collections.sort(utils_Utils.getSortFunction(this.i18nService, "name"))));
    }
    // Transforms the input CollectionViews into TreeNodes
    getAllNested(collections) {
        const groupedByOrg = this.groupByOrganization(collections);
        const all = [];
        for (const group of groupedByOrg.values()) {
            const nodes = [];
            for (const c of group) {
                const collectionCopy = Object.assign(new CollectionView(Object.assign(Object.assign({}, c), { name: c.name })), c);
                const parts = c.name ? c.name.replace(/^\/+|\/+$/g, "").split(default_collection_service_NestingDelimiter) : [];
                ServiceUtils.nestedTraverse(nodes, 0, parts, collectionCopy, undefined, default_collection_service_NestingDelimiter);
            }
            all.push(...nodes);
        }
        return all;
    }
    groupByOrganization(collections) {
        const groupedByOrg = new Map();
        collections.map((c) => {
            var _a;
            const key = c.organizationId;
            ((_a = groupedByOrg.get(key)) !== null && _a !== void 0 ? _a : groupedByOrg.set(key, []).get(key)).push(c);
        });
        return groupedByOrg;
    }
    /**
     * @deprecated August 30 2022: Moved to new Vault Filter Service
     * Remove when Desktop and Browser are updated
     */
    getNested(collections, id) {
        const nestedCollections = this.getAllNested(collections);
        return ServiceUtils.getTreeNodeObjectFromList(nestedCollections, id);
    }
    /**
     * Sets the decrypted collections state for a user.
     * @param collections the decrypted collections
     * @param userId the user id
     */
    setDecryptedCollections(collections, userId) {
        return default_collection_service_awaiter(this, void 0, void 0, function* () {
            yield this.stateProvider.setUserState(DECRYPTED_COLLECTION_DATA_KEY, collections, userId);
        });
    }
}

;// ../../libs/admin-console/src/common/collections/services/index.ts



;// ../../libs/admin-console/src/common/collections/index.ts




;// ../../libs/admin-console/src/common/organization-user/models/requests/organization-user-bulk.request.ts
class OrganizationUserBulkRequest {
    constructor(ids) {
        this.ids = ids == null ? [] : ids;
    }
}

;// ../../libs/common/src/admin-console/models/api/permissions.api.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

class PermissionsApi extends BaseResponse {
    constructor(data = null) {
        super(data);
        if (data == null) {
            return this;
        }
        this.accessEventLogs = this.getResponseProperty("AccessEventLogs");
        this.accessImportExport = this.getResponseProperty("AccessImportExport");
        this.accessReports = this.getResponseProperty("AccessReports");
        this.createNewCollections = this.getResponseProperty("CreateNewCollections");
        this.editAnyCollection = this.getResponseProperty("EditAnyCollection");
        this.deleteAnyCollection = this.getResponseProperty("DeleteAnyCollection");
        this.manageCiphers = this.getResponseProperty("ManageCiphers");
        this.manageGroups = this.getResponseProperty("ManageGroups");
        this.manageSso = this.getResponseProperty("ManageSso");
        this.managePolicies = this.getResponseProperty("ManagePolicies");
        this.manageUsers = this.getResponseProperty("ManageUsers");
        this.manageResetPassword = this.getResponseProperty("ManageResetPassword");
        this.manageScim = this.getResponseProperty("ManageScim");
    }
}

;// ../../libs/admin-console/src/common/organization-user/models/responses/organization-user.response.ts



class OrganizationUserResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.collections = [];
        this.groups = [];
        this.id = this.getResponseProperty("Id");
        this.userId = this.getResponseProperty("UserId");
        this.type = this.getResponseProperty("Type");
        this.status = this.getResponseProperty("Status");
        this.permissions = new PermissionsApi(this.getResponseProperty("Permissions"));
        this.externalId = this.getResponseProperty("ExternalId");
        this.accessSecretsManager = this.getResponseProperty("AccessSecretsManager");
        this.resetPasswordEnrolled = this.getResponseProperty("ResetPasswordEnrolled");
        this.hasMasterPassword = this.getResponseProperty("HasMasterPassword");
        const collections = this.getResponseProperty("Collections");
        if (collections != null) {
            this.collections = collections.map((c) => new SelectionReadOnlyResponse(c));
        }
        const groups = this.getResponseProperty("Groups");
        if (groups != null) {
            this.groups = groups;
        }
    }
}
class OrganizationUserUserDetailsResponse extends OrganizationUserResponse {
    constructor(response) {
        var _a, _b;
        super(response);
        this.name = this.getResponseProperty("Name");
        this.email = this.getResponseProperty("Email");
        this.avatarColor = this.getResponseProperty("AvatarColor");
        this.twoFactorEnabled = this.getResponseProperty("TwoFactorEnabled");
        this.usesKeyConnector = (_a = this.getResponseProperty("UsesKeyConnector")) !== null && _a !== void 0 ? _a : false;
        this.managedByOrganization = (_b = this.getResponseProperty("ManagedByOrganization")) !== null && _b !== void 0 ? _b : false;
    }
}
class OrganizationUserDetailsResponse extends OrganizationUserResponse {
    constructor(response) {
        var _a;
        super(response);
        this.managedByOrganization = (_a = this.getResponseProperty("ManagedByOrganization")) !== null && _a !== void 0 ? _a : false;
        this.ssoExternalId = this.getResponseProperty("SsoExternalId");
    }
}
class OrganizationUserResetPasswordDetailsResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.organizationUserId = this.getResponseProperty("OrganizationUserId");
        this.kdf = this.getResponseProperty("Kdf");
        this.kdfIterations = this.getResponseProperty("KdfIterations");
        this.kdfMemory = this.getResponseProperty("KdfMemory");
        this.kdfParallelism = this.getResponseProperty("KdfParallelism");
        this.resetPasswordKey = this.getResponseProperty("ResetPasswordKey");
        this.encryptedPrivateKey = this.getResponseProperty("EncryptedPrivateKey");
    }
}

;// ../../libs/admin-console/src/common/organization-user/models/responses/organization-user-bulk.response.ts

class OrganizationUserBulkResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.id = this.getResponseProperty("Id");
        this.error = this.getResponseProperty("Error");
    }
}

;// ../../libs/admin-console/src/common/organization-user/models/responses/organization-user-bulk-public-key.response.ts

class OrganizationUserBulkPublicKeyResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.id = this.getResponseProperty("Id");
        this.userId = this.getResponseProperty("UserId");
        this.key = this.getResponseProperty("Key");
    }
}

;// ../../libs/admin-console/src/common/organization-user/models/responses/organization-user-mini.response.ts

class OrganizationUserUserMiniResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.id = this.getResponseProperty("Id");
        this.userId = this.getResponseProperty("UserId");
        this.email = this.getResponseProperty("Email");
        this.name = this.getResponseProperty("Name");
        this.type = this.getResponseProperty("Type");
        this.status = this.getResponseProperty("Status");
    }
}

;// ../../libs/admin-console/src/common/organization-user/models/responses/index.ts





;// ../../libs/admin-console/src/common/organization-user/services/default-organization-user-api.service.ts
var default_organization_user_api_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};



class DefaultOrganizationUserApiService {
    constructor(apiService) {
        this.apiService = apiService;
    }
    getOrganizationUser(organizationId, id, options) {
        return default_organization_user_api_service_awaiter(this, void 0, void 0, function* () {
            const params = new URLSearchParams();
            if (options === null || options === void 0 ? void 0 : options.includeGroups) {
                params.set("includeGroups", "true");
            }
            const r = yield this.apiService.send("GET", `/organizations/${organizationId}/users/${id}?${params.toString()}`, null, true, true);
            return new OrganizationUserDetailsResponse(r);
        });
    }
    getAllUsers(organizationId, options) {
        return default_organization_user_api_service_awaiter(this, void 0, void 0, function* () {
            const params = new URLSearchParams();
            if (options === null || options === void 0 ? void 0 : options.includeCollections) {
                params.set("includeCollections", "true");
            }
            if (options === null || options === void 0 ? void 0 : options.includeGroups) {
                params.set("includeGroups", "true");
            }
            const r = yield this.apiService.send("GET", `/organizations/${organizationId}/users?${params.toString()}`, null, true, true);
            return new ListResponse(r, OrganizationUserUserDetailsResponse);
        });
    }
    getAllMiniUserDetails(organizationId) {
        return default_organization_user_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("GET", `/organizations/${organizationId}/users/mini-details`, null, true, true);
            return new ListResponse(r, OrganizationUserUserMiniResponse);
        });
    }
    getOrganizationUserResetPasswordDetails(organizationId, id) {
        return default_organization_user_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("GET", "/organizations/" + organizationId + "/users/" + id + "/reset-password-details", null, true, true);
            return new OrganizationUserResetPasswordDetailsResponse(r);
        });
    }
    getManyOrganizationUserAccountRecoveryDetails(organizationId, ids) {
        return default_organization_user_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("POST", "/organizations/" + organizationId + "/users/account-recovery-details", new OrganizationUserBulkRequest(ids), true, true);
            return new ListResponse(r, OrganizationUserResetPasswordDetailsResponse);
        });
    }
    postOrganizationUserInvite(organizationId, request) {
        return this.apiService.send("POST", "/organizations/" + organizationId + "/users/invite", request, true, false);
    }
    postOrganizationUserReinvite(organizationId, id) {
        return this.apiService.send("POST", "/organizations/" + organizationId + "/users/" + id + "/reinvite", null, true, false);
    }
    postManyOrganizationUserReinvite(organizationId, ids) {
        return default_organization_user_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("POST", "/organizations/" + organizationId + "/users/reinvite", new OrganizationUserBulkRequest(ids), true, true);
            return new ListResponse(r, OrganizationUserBulkResponse);
        });
    }
    postOrganizationUserAcceptInit(organizationId, id, request) {
        return this.apiService.send("POST", "/organizations/" + organizationId + "/users/" + id + "/accept-init", request, true, false);
    }
    postOrganizationUserAccept(organizationId, id, request) {
        return this.apiService.send("POST", "/organizations/" + organizationId + "/users/" + id + "/accept", request, true, false);
    }
    postOrganizationUserConfirm(organizationId, id, request) {
        return this.apiService.send("POST", "/organizations/" + organizationId + "/users/" + id + "/confirm", request, true, false);
    }
    postOrganizationUserAutoConfirm(organizationId, id, request) {
        return this.apiService.send("POST", "/organizations/" + organizationId + "/users/" + id + "/auto-confirm", request, true, false);
    }
    postOrganizationUsersPublicKey(organizationId, ids) {
        return default_organization_user_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("POST", "/organizations/" + organizationId + "/users/public-keys", new OrganizationUserBulkRequest(ids), true, true);
            return new ListResponse(r, OrganizationUserBulkPublicKeyResponse);
        });
    }
    postOrganizationUserBulkConfirm(organizationId, request) {
        return default_organization_user_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("POST", "/organizations/" + organizationId + "/users/confirm", request, true, true);
            return new ListResponse(r, OrganizationUserBulkResponse);
        });
    }
    putOrganizationUserBulkEnableSecretsManager(organizationId, ids) {
        return default_organization_user_api_service_awaiter(this, void 0, void 0, function* () {
            yield this.apiService.send("PUT", "/organizations/" + organizationId + "/users/enable-secrets-manager", new OrganizationUserBulkRequest(ids), true, false);
        });
    }
    putOrganizationUser(organizationId, id, request) {
        return this.apiService.send("PUT", "/organizations/" + organizationId + "/users/" + id, request, true, false);
    }
    putOrganizationUserResetPasswordEnrollment(organizationId, userId, request) {
        return this.apiService.send("PUT", "/organizations/" + organizationId + "/users/" + userId + "/reset-password-enrollment", request, true, false);
    }
    putOrganizationUserResetPassword(organizationId, id, request) {
        return this.apiService.send("PUT", "/organizations/" + organizationId + "/users/" + id + "/reset-password", request, true, false);
    }
    putOrganizationUserRecoverAccount(organizationId, id, request) {
        return this.apiService.send("PUT", "/organizations/" + organizationId + "/users/" + id + "/recover-account", request, true, false);
    }
    removeOrganizationUser(organizationId, id) {
        return this.apiService.send("DELETE", "/organizations/" + organizationId + "/users/" + id, null, true, false);
    }
    removeManyOrganizationUsers(organizationId, ids) {
        return default_organization_user_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("DELETE", "/organizations/" + organizationId + "/users", new OrganizationUserBulkRequest(ids), true, true);
            return new ListResponse(r, OrganizationUserBulkResponse);
        });
    }
    revokeOrganizationUser(organizationId, id) {
        return this.apiService.send("PUT", "/organizations/" + organizationId + "/users/" + id + "/revoke", null, true, false);
    }
    revokeManyOrganizationUsers(organizationId, ids) {
        return default_organization_user_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("PUT", "/organizations/" + organizationId + "/users/revoke", new OrganizationUserBulkRequest(ids), true, true);
            return new ListResponse(r, OrganizationUserBulkResponse);
        });
    }
    revokeSelf(organizationId) {
        return this.apiService.send("PUT", "/organizations/" + organizationId + "/users/revoke-self", null, true, false);
    }
    restoreOrganizationUser(organizationId, id, request) {
        return this.apiService.send("PUT", "/organizations/" + organizationId + "/users/" + id + "/restore/vnext", request, true, false);
    }
    restoreManyOrganizationUsers(organizationId, request) {
        return default_organization_user_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("PUT", "/organizations/" + organizationId + "/users/restore", request, true, true);
            return new ListResponse(r, OrganizationUserBulkResponse);
        });
    }
    deleteOrganizationUser(organizationId, id) {
        return this.apiService.send("DELETE", "/organizations/" + organizationId + "/users/" + id + "/delete-account", null, true, false);
    }
    deleteManyOrganizationUsers(organizationId, ids) {
        return default_organization_user_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("DELETE", "/organizations/" + organizationId + "/users/delete-account", new OrganizationUserBulkRequest(ids), true, true);
            return new ListResponse(r, OrganizationUserBulkResponse);
        });
    }
}

;// ../../libs/admin-console/src/common/organization-user/services/default-organization-user.service.ts





class DefaultOrganizationUserService {
    constructor(keyService, encryptService, organizationUserApiService, accountService, i18nService) {
        this.keyService = keyService;
        this.encryptService = encryptService;
        this.organizationUserApiService = organizationUserApiService;
        this.accountService = accountService;
        this.i18nService = i18nService;
    }
    orgKey$(organization) {
        return this.accountService.activeAccount$.pipe(getUserId, switchMap((userId) => this.keyService.orgKeys$(userId)), filter((orgKeys) => !!orgKeys), map((organizationKeysById) => organizationKeysById[organization.id]));
    }
    buildConfirmRequest(organization, publicKey) {
        const encryptedCollectionName$ = this.getEncryptedDefaultCollectionName$(organization);
        const encryptedKey$ = this.orgKey$(organization).pipe(switchMap((orgKey) => this.encryptService.encapsulateKeyUnsigned(orgKey, publicKey)));
        return combineLatest([encryptedKey$, encryptedCollectionName$]).pipe(map(([key, collectionName]) => ({
            key: key.encryptedString,
            defaultUserCollectionName: collectionName.encryptedString,
        })));
    }
    confirmUser(organization, userId, publicKey) {
        return this.buildConfirmRequest(organization, publicKey).pipe(switchMap((request) => this.organizationUserApiService.postOrganizationUserConfirm(organization.id, userId, request)));
    }
    bulkConfirmUsers(organization, userIdsWithKeys) {
        return this.getEncryptedDefaultCollectionName$(organization).pipe(switchMap((collectionName) => {
            const request = new OrganizationUserBulkConfirmRequest(userIdsWithKeys, collectionName.encryptedString);
            return this.organizationUserApiService.postOrganizationUserBulkConfirm(organization.id, request);
        }));
    }
    buildRestoreUserRequest(organization) {
        return this.getEncryptedDefaultCollectionName$(organization).pipe(map((collectionName) => new OrganizationUserRestoreRequest(collectionName.encryptedString)));
    }
    restoreUser(organization, userId) {
        return this.buildRestoreUserRequest(organization).pipe(switchMap((request) => this.organizationUserApiService.restoreOrganizationUser(organization.id, userId, request)));
    }
    bulkRestoreUsers(organization, userIds) {
        return this.getEncryptedDefaultCollectionName$(organization).pipe(switchMap((collectionName) => {
            const request = new OrganizationUserBulkRestoreRequest(userIds, collectionName.encryptedString);
            return this.organizationUserApiService.restoreManyOrganizationUsers(organization.id, request);
        }));
    }
    getEncryptedDefaultCollectionName$(organization) {
        return this.orgKey$(organization).pipe(switchMap((orgKey) => this.encryptService.encryptString(this.i18nService.t("myItems"), orgKey)));
    }
}

;// ../../libs/admin-console/src/common/organization-user/services/index.ts



;// ../../libs/admin-console/src/common/organization-user/models/requests/organization-user-confirm.request.ts
class OrganizationUserConfirmRequest {
}

;// ../../libs/admin-console/src/common/organization-user/models/requests/index.ts










;// ../../libs/admin-console/src/common/organization-user/models/index.ts



;// ../../libs/admin-console/src/common/organization-user/index.ts




;// ../../libs/admin-console/src/common/index.ts



;// ./src/admin-console/commands/confirm.command.ts
var confirm_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore






class ConfirmCommand {
    constructor(apiService, keyService, encryptService, organizationUserApiService, accountService, i18nService) {
        this.apiService = apiService;
        this.keyService = keyService;
        this.encryptService = encryptService;
        this.organizationUserApiService = organizationUserApiService;
        this.accountService = accountService;
        this.i18nService = i18nService;
    }
    run(object, id, cmdOptions) {
        return confirm_command_awaiter(this, void 0, void 0, function* () {
            if (id != null) {
                id = id.toLowerCase();
            }
            const normalizedOptions = new confirm_command_Options(cmdOptions);
            switch (object.toLowerCase()) {
                case "org-member":
                    return yield this.confirmOrganizationMember(id, normalizedOptions);
                default:
                    return response_Response.badRequest("Unknown object.");
            }
        });
    }
    confirmOrganizationMember(id, options) {
        return confirm_command_awaiter(this, void 0, void 0, function* () {
            if (options.organizationId == null || options.organizationId === "") {
                return response_Response.badRequest("--organizationid <organizationid> required.");
            }
            if (!utils_Utils.isGuid(id)) {
                return response_Response.badRequest("`" + id + "` is not a GUID.");
            }
            if (!utils_Utils.isGuid(options.organizationId)) {
                return response_Response.badRequest("`" + options.organizationId + "` is not a GUID.");
            }
            try {
                const orgKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId, (0,external_rxjs_namespaceObject.switchMap)((userId) => this.keyService.orgKeys$(userId)), (0,external_rxjs_namespaceObject.map)((orgKeys) => { var _a; return (_a = orgKeys[options.organizationId]) !== null && _a !== void 0 ? _a : null; })));
                if (orgKey == null) {
                    throw new Error("No encryption key for this organization.");
                }
                const orgUser = yield this.organizationUserApiService.getOrganizationUser(options.organizationId, id);
                if (orgUser == null) {
                    throw new Error("Member id does not exist for this organization.");
                }
                this.validateOrganizationUserStatus(orgUser);
                const publicKeyResponse = yield this.apiService.getUserPublicKey(orgUser.userId);
                const publicKey = utils_Utils.fromB64ToArray(publicKeyResponse.publicKey);
                const key = yield this.encryptService.encapsulateKeyUnsigned(orgKey, publicKey);
                const req = new OrganizationUserConfirmRequest();
                req.key = key.encryptedString;
                req.defaultUserCollectionName = yield this.getEncryptedDefaultUserCollectionName(orgKey);
                yield this.organizationUserApiService.postOrganizationUserConfirm(options.organizationId, id, req);
                return response_Response.success();
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
    getEncryptedDefaultUserCollectionName(orgKey) {
        return confirm_command_awaiter(this, void 0, void 0, function* () {
            const defaultCollectionName = this.i18nService.t("myItems");
            const encrypted = yield this.encryptService.encryptString(defaultCollectionName, orgKey);
            return encrypted.encryptedString;
        });
    }
    validateOrganizationUserStatus(orgUser) {
        if (orgUser.status === organization_user_status_type_enum_OrganizationUserStatusType.Invited) {
            throw new Error("User must accept the invitation before they can be confirmed.");
        }
        if (orgUser.status === organization_user_status_type_enum_OrganizationUserStatusType.Confirmed) {
            throw new Error("User is already confirmed.");
        }
        if (orgUser.status === organization_user_status_type_enum_OrganizationUserStatusType.Revoked) {
            throw new Error("User is revoked and cannot be confirmed.");
        }
        if (orgUser.status !== organization_user_status_type_enum_OrganizationUserStatusType.Accepted) {
            throw new Error("User is not in a valid state to be confirmed.");
        }
    }
}
class confirm_command_Options {
    constructor(passedOptions) {
        this.organizationId = (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.organizationid) || (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.organizationId);
    }
}

;// ../../libs/common/src/vault/enums/cipher-reprompt-type.ts
const CipherRepromptType = {
    None: 0,
    Password: 1,
};
/**
 * Normalizes a CipherRepromptType value to ensure compatibility with the SDK.
 * @param value - The cipher reprompt type from user data
 * @returns Valid CipherRepromptType, defaults to CipherRepromptType.None if unrecognized
 */
function normalizeCipherRepromptTypeForSdk(value) {
    switch (value) {
        case CipherRepromptType.None:
        case CipherRepromptType.Password:
            return value;
        default:
            return CipherRepromptType.None;
    }
}

;// ../../libs/common/src/vault/enums/cipher-type.ts
const _CipherType = Object.freeze({
    Login: 1,
    SecureNote: 2,
    Card: 3,
    Identity: 4,
    SshKey: 5,
});
// FIXME: Update typing of `CipherType` to be `Record<keyof _CipherType, CipherType>` which is ADR-0025 compliant when the TypeScript version is at least 5.8.
const CipherType = _CipherType;
/**
 * Reverse mapping of Cipher Types to their associated names.
 * Prefer using {@link toCipherTypeName} rather than accessing this object directly.
 *
 * When represented as an enum in TypeScript, this mapping was provided
 * by default. Now using a constant object it needs to be defined manually.
 */
const cipherTypeNames = Object.freeze(Object.fromEntries(Object.entries(CipherType).map(([key, value]) => [value, key])));
/**
 * Returns the associated name for the cipher type, will throw when the name is not found.
 */
function toCipherTypeName(type) {
    const name = cipherTypeNames[type];
    return name;
}
/**
 * @returns `true` if the value is a valid `CipherType`, `false` otherwise.
 */
const isCipherType = (value) => {
    return Object.values(CipherType).includes(value);
};
/**
 * Converts a value to a `CipherType` if it is valid, otherwise returns `null`.
 */
const toCipherType = (value) => {
    if (isCipherType(value)) {
        return value;
    }
    if (typeof value === "string") {
        const valueAsInt = parseInt(value, 10);
        if (isCipherType(valueAsInt)) {
            return valueAsInt;
        }
    }
    return undefined;
};

;// ../../libs/common/src/platform/abstractions/sdk/sdk.service.ts


class UserNotLoggedInError extends Error {
    constructor(userId) {
        super(`User (${userId}) is not logged in`);
    }
}
class InvalidUuid extends Error {
    constructor(uuid) {
        super(`Invalid UUID: ${uuid}`);
    }
}
function toSdkDevice(device) {
    switch (device) {
        case DeviceType.Android:
            return "Android";
        case DeviceType.iOS:
            return "iOS";
        case DeviceType.ChromeExtension:
            return "ChromeExtension";
        case DeviceType.FirefoxExtension:
            return "FirefoxExtension";
        case DeviceType.OperaExtension:
            return "OperaExtension";
        case DeviceType.EdgeExtension:
            return "EdgeExtension";
        case DeviceType.WindowsDesktop:
            return "WindowsDesktop";
        case DeviceType.MacOsDesktop:
            return "MacOsDesktop";
        case DeviceType.LinuxDesktop:
            return "LinuxDesktop";
        case DeviceType.ChromeBrowser:
            return "ChromeBrowser";
        case DeviceType.FirefoxBrowser:
            return "FirefoxBrowser";
        case DeviceType.OperaBrowser:
            return "OperaBrowser";
        case DeviceType.EdgeBrowser:
            return "EdgeBrowser";
        case DeviceType.IEBrowser:
            return "IEBrowser";
        case DeviceType.UnknownBrowser:
            return "UnknownBrowser";
        case DeviceType.AndroidAmazon:
            return "AndroidAmazon";
        case DeviceType.UWP:
            return "UWP";
        case DeviceType.SafariBrowser:
            return "SafariBrowser";
        case DeviceType.VivaldiBrowser:
            return "VivaldiBrowser";
        case DeviceType.VivaldiExtension:
            return "VivaldiExtension";
        case DeviceType.SafariExtension:
            return "SafariExtension";
        case DeviceType.Server:
            return "Server";
        case DeviceType.WindowsCLI:
            return "WindowsCLI";
        case DeviceType.MacOsCLI:
            return "MacOsCLI";
        case DeviceType.LinuxCLI:
            return "LinuxCLI";
        default:
            return "SDK";
    }
}
/**
 * Converts a string to UUID. Will throw an error if the UUID is non valid.
 */
function asUuid(uuid) {
    if (utils_Utils.isGuid(uuid)) {
        return uuid;
    }
    throw new InvalidUuid(uuid);
}
/**
 * Converts a UUID to the string representation.
 */
function uuidAsString(uuid) {
    return uuid;
}
class SdkService {
}

;// ../../libs/common/src/platform/services/cryptography/initializer-key.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var InitializerKey;
(function (InitializerKey) {
    InitializerKey[InitializerKey["Cipher"] = 0] = "Cipher";
    InitializerKey[InitializerKey["CipherView"] = 1] = "CipherView";
})(InitializerKey || (InitializerKey = {}));

;// ../../libs/common/src/vault/utils/domain-utils.ts

/**
 * Converts a string value to an EncString, handling null/undefined gracefully.
 *
 * @param value - The string value to convert, or undefined
 * @returns An EncString instance if value is defined, otherwise undefined
 *
 */
const conditionalEncString = (value) => {
    return value != null ? new enc_string_EncString(value) : undefined;
};
/**
 * Converts an EncString representation (from JSON or SDK) to a domain EncString instance.
 * Handles both serialized JSON representations and SDK EncString objects.
 *
 * @param value - The EncString representation (string, object, or SdkEncString), or undefined
 * @returns A domain EncString instance if value is defined, otherwise undefined
 *
 */
const encStringFrom = (value) => {
    return value != null ? enc_string_EncString.fromJSON(value) : undefined;
};

;// ../../libs/common/src/vault/models/api/cipher-permissions.api.ts

class CipherPermissionsApi extends BaseResponse {
    constructor(data = null) {
        super(data);
        this.delete = false;
        this.restore = false;
        if (data == null) {
            return;
        }
        this.delete = this.getResponseProperty("Delete");
        this.restore = this.getResponseProperty("Restore");
    }
    static fromJSON(obj) {
        return Object.assign(new CipherPermissionsApi(), obj);
    }
    /**
     * Converts the SDK CipherPermissionsApi to a CipherPermissionsApi.
     */
    static fromSdkCipherPermissions(obj) {
        if (!obj) {
            return undefined;
        }
        const permissions = new CipherPermissionsApi();
        permissions.delete = obj.delete;
        permissions.restore = obj.restore;
        return permissions;
    }
    /**
     * Converts the CipherPermissionsApi to an SdkCipherPermissions
     */
    toSdkCipherPermissions() {
        return this;
    }
}

;// ../../libs/common/src/vault/models/data/attachment.data.ts
class AttachmentData {
    constructor(response) {
        if (response == null) {
            return;
        }
        this.id = response.id;
        this.url = response.url;
        this.fileName = response.fileName;
        this.key = response.key;
        this.size = response.size;
        this.sizeName = response.sizeName;
    }
}

;// ../../libs/common/src/vault/models/data/card.data.ts
class CardData {
    constructor(data) {
        if (data == null) {
            return;
        }
        this.cardholderName = data.cardholderName;
        this.brand = data.brand;
        this.number = data.number;
        this.expMonth = data.expMonth;
        this.expYear = data.expYear;
        this.code = data.code;
    }
}

;// ../../libs/common/src/vault/enums/field-type.enum.ts
const _FieldType = Object.freeze({
    Text: 0,
    Hidden: 1,
    Boolean: 2,
    Linked: 3,
});
const FieldType = _FieldType;
/**
 * Normalizes a FieldType value to ensure compatibility with the SDK.
 * @param value - The field type from user data
 * @returns Valid FieldType, defaults to FieldType.Text if unrecognized
 */
function normalizeFieldTypeForSdk(value) {
    switch (value) {
        case FieldType.Text:
        case FieldType.Hidden:
        case FieldType.Boolean:
        case FieldType.Linked:
            return value;
        default:
            return FieldType.Text;
    }
}

;// ../../libs/common/src/vault/enums/linked-id-type.enum.ts
// LoginView
const LoginLinkedId = {
    Username: 100,
    Password: 101,
};
// CardView
const CardLinkedId = {
    CardholderName: 300,
    ExpMonth: 301,
    ExpYear: 302,
    Code: 303,
    Brand: 304,
    Number: 305,
};
// IdentityView
const IdentityLinkedId = {
    Title: 400,
    MiddleName: 401,
    Address1: 402,
    Address2: 403,
    Address3: 404,
    City: 405,
    State: 406,
    PostalCode: 407,
    Country: 408,
    Company: 409,
    Email: 410,
    Phone: 411,
    Ssn: 412,
    Username: 413,
    PassportNumber: 414,
    LicenseNumber: 415,
    FirstName: 416,
    LastName: 417,
    FullName: 418,
};
/**
 * Normalizes a LinkedIdType value to ensure compatibility with the SDK.
 * @param value - The linked ID type from user data
 * @returns Valid LinkedIdType or undefined if unrecognized
 */
function normalizeLinkedIdTypeForSdk(value) {
    if (value == null) {
        return undefined;
    }
    // Check all valid LinkedId numeric values (100-418)
    const allValidValues = [
        ...Object.values(LoginLinkedId),
        ...Object.values(CardLinkedId),
        ...Object.values(IdentityLinkedId),
    ];
    return allValidValues.includes(value) ? value : undefined;
}

;// ../../libs/common/src/vault/enums/secure-note-type.enum.ts
const SecureNoteType = {
    Generic: 0,
};
/**
 * Normalizes a SecureNoteType value to ensure compatibility with the SDK.
 * @param value - The secure note type from user data
 * @returns Valid SecureNoteType, defaults to SecureNoteType.Generic if unrecognized
 */
function normalizeSecureNoteTypeForSdk(value) {
    return SecureNoteType.Generic;
}

;// ../../libs/common/src/vault/enums/extension-page-urls.enum.ts
/**
 * Available pages within the extension by their URL.
 * Useful when opening a specific page within the popup.
 */
const ExtensionPageUrls = {
    Index: "popup/index.html#/",
    AtRiskPasswords: "popup/index.html#/at-risk-passwords",
};

;// ../../libs/common/src/vault/enums/index.ts







;// ../../libs/common/src/vault/models/data/field.data.ts

class FieldData {
    constructor(response) {
        this.type = FieldType.Text;
        if (response == null) {
            return;
        }
        this.type = response.type;
        this.name = response.name;
        this.value = response.value;
        this.linkedId = response.linkedId;
    }
}

;// ../../libs/common/src/vault/models/data/identity.data.ts
class IdentityData {
    constructor(data) {
        if (data == null) {
            return;
        }
        this.title = data.title;
        this.firstName = data.firstName;
        this.middleName = data.middleName;
        this.lastName = data.lastName;
        this.address1 = data.address1;
        this.address2 = data.address2;
        this.address3 = data.address3;
        this.city = data.city;
        this.state = data.state;
        this.postalCode = data.postalCode;
        this.country = data.country;
        this.company = data.company;
        this.email = data.email;
        this.phone = data.phone;
        this.ssn = data.ssn;
        this.username = data.username;
        this.passportNumber = data.passportNumber;
        this.licenseNumber = data.licenseNumber;
    }
}

;// ../../libs/common/src/vault/models/data/fido2-credential.data.ts
class Fido2CredentialData {
    constructor(data) {
        if (data == null) {
            return;
        }
        this.credentialId = data.credentialId;
        this.keyType = data.keyType;
        this.keyAlgorithm = data.keyAlgorithm;
        this.keyCurve = data.keyCurve;
        this.keyValue = data.keyValue;
        this.rpId = data.rpId;
        this.userHandle = data.userHandle;
        this.userName = data.userName;
        this.counter = data.counter;
        this.rpName = data.rpName;
        this.userDisplayName = data.userDisplayName;
        this.discoverable = data.discoverable;
        this.creationDate = data.creationDate;
    }
}

;// ../../libs/common/src/vault/models/data/login-uri.data.ts
class LoginUriData {
    constructor(data) {
        if (data == null) {
            return;
        }
        this.uri = data.uri;
        this.uriChecksum = data.uriChecksum;
        this.match = data.match;
    }
}

;// ../../libs/common/src/vault/models/data/login.data.ts


class LoginData {
    constructor(data) {
        var _a;
        if (data == null) {
            return;
        }
        this.username = data.username;
        this.password = data.password;
        this.passwordRevisionDate = data.passwordRevisionDate;
        this.totp = data.totp;
        this.autofillOnPageLoad = data.autofillOnPageLoad;
        if (data.uris) {
            this.uris = data.uris.map((u) => new LoginUriData(u));
        }
        if (data.fido2Credentials) {
            this.fido2Credentials = (_a = data.fido2Credentials) === null || _a === void 0 ? void 0 : _a.map((key) => new Fido2CredentialData(key));
        }
    }
}

;// ../../libs/common/src/vault/models/data/password-history.data.ts
class PasswordHistoryData {
    constructor(response) {
        if (response == null) {
            return;
        }
        this.password = response.password;
        this.lastUsedDate = response.lastUsedDate;
    }
}

;// ../../libs/common/src/vault/models/data/secure-note.data.ts

class SecureNoteData {
    constructor(data) {
        this.type = SecureNoteType.Generic;
        if (data == null) {
            return;
        }
        this.type = data.type;
    }
}

;// ../../libs/common/src/vault/models/data/ssh-key.data.ts
class SshKeyData {
    constructor(data) {
        if (data == null) {
            return;
        }
        this.privateKey = data.privateKey;
        this.publicKey = data.publicKey;
        this.keyFingerprint = data.keyFingerprint;
    }
}

;// ../../libs/common/src/vault/models/data/cipher.data.ts











class CipherData {
    constructor(response, collectionIds) {
        this.id = "";
        this.edit = false;
        this.viewPassword = true;
        this.organizationUseTotp = false;
        this.favorite = false;
        this.type = CipherType.Login;
        this.name = "";
        this.reprompt = CipherRepromptType.None;
        if (response == null) {
            this.creationDate = this.revisionDate = new Date().toISOString();
            return;
        }
        this.id = response.id;
        this.organizationId = response.organizationId;
        this.folderId = response.folderId;
        this.edit = response.edit;
        this.viewPassword = response.viewPassword;
        this.permissions = response.permissions;
        this.organizationUseTotp = response.organizationUseTotp;
        this.favorite = response.favorite;
        this.revisionDate = response.revisionDate;
        this.type = response.type;
        this.name = response.name;
        this.notes = response.notes;
        this.collectionIds = collectionIds != null ? collectionIds : response.collectionIds;
        this.creationDate = response.creationDate;
        this.deletedDate = response.deletedDate;
        this.archivedDate = response.archivedDate;
        this.reprompt = response.reprompt;
        this.key = response.key;
        switch (this.type) {
            case CipherType.Login:
                this.login = new LoginData(response.login);
                break;
            case CipherType.SecureNote:
                this.secureNote = new SecureNoteData(response.secureNote);
                break;
            case CipherType.Card:
                this.card = new CardData(response.card);
                break;
            case CipherType.Identity:
                this.identity = new IdentityData(response.identity);
                break;
            case CipherType.SshKey:
                this.sshKey = new SshKeyData(response.sshKey);
                break;
            default:
                break;
        }
        if (response.fields != null) {
            this.fields = response.fields.map((f) => new FieldData(f));
        }
        if (response.attachments != null) {
            this.attachments = response.attachments.map((a) => new AttachmentData(a));
        }
        if (response.passwordHistory != null) {
            this.passwordHistory = response.passwordHistory.map((ph) => new PasswordHistoryData(ph));
        }
    }
    static fromJSON(obj) {
        const result = Object.assign(new CipherData(), obj);
        if (obj.permissions != null) {
            result.permissions = CipherPermissionsApi.fromJSON(obj.permissions);
        }
        return result;
    }
}

;// ../../libs/common/src/vault/models/data/local.data.ts
/**
 * Convert the SdkLocalDataView to LocalData
 * @param localData
 */
function fromSdkLocalData(localData) {
    if (localData == null) {
        return undefined;
    }
    return {
        lastUsedDate: localData.lastUsedDate ? new Date(localData.lastUsedDate).getTime() : undefined,
        lastLaunched: localData.lastLaunched ? new Date(localData.lastLaunched).getTime() : undefined,
    };
}
/**
 * Convert the LocalData to SdkLocalData
 * @param localData
 */
function toSdkLocalData(localData) {
    if (localData == null) {
        return undefined;
    }
    return {
        lastUsedDate: localData.lastUsedDate
            ? new Date(localData.lastUsedDate).toISOString()
            : undefined,
        lastLaunched: localData.lastLaunched
            ? new Date(localData.lastLaunched).toISOString()
            : undefined,
    };
}

;// ../../libs/common/src/vault/models/view/attachment.view.ts


class AttachmentView {
    constructor(a) {
        if (!a) {
            return;
        }
        this.id = a.id;
        this.url = a.url;
        this.size = a.size;
        this.sizeName = a.sizeName;
    }
    get fileSize() {
        try {
            if (this.size != null) {
                return parseInt(this.size);
            }
        }
        catch (_a) {
            // Invalid file size.
        }
        return 0;
    }
    get hasDecryptionError() {
        return this._hasDecryptionError || this.fileName === DECRYPT_ERROR;
    }
    set hasDecryptionError(value) {
        this._hasDecryptionError = value;
    }
    static fromJSON(obj) {
        const key = obj.key == null ? null : SymmetricCryptoKey.fromJSON(obj.key);
        let encryptedKey;
        if (obj.encryptedKey != null) {
            if (typeof obj.encryptedKey === "string") {
                // If the key is a string, we need to parse it as EncString
                encryptedKey = enc_string_EncString.fromJSON(obj.encryptedKey);
            }
            else if (obj.encryptedKey instanceof enc_string_EncString) {
                // If the key is already an EncString instance, we can use it directly
                encryptedKey = obj.encryptedKey;
            }
        }
        return Object.assign(new AttachmentView(), obj, { key: key, encryptedKey: encryptedKey });
    }
    /**
     * Converts the AttachmentView to a SDK AttachmentView.
     */
    toSdkAttachmentView() {
        var _a;
        return {
            id: this.id,
            url: this.url,
            size: this.size,
            sizeName: this.sizeName,
            fileName: this.fileName,
            key: (_a = this.encryptedKey) === null || _a === void 0 ? void 0 : _a.toSdk(),
            // TODO: PM-23005 - Temporary field, should be removed when encrypted migration is complete
            decryptedKey: this.key ? this.key.toBase64() : undefined,
        };
    }
    /**
     * Converts the SDK AttachmentView to a AttachmentView.
     */
    static fromSdkAttachmentView(obj, failure = false) {
        if (!obj) {
            return undefined;
        }
        const view = new AttachmentView();
        view.id = obj.id;
        view.url = obj.url;
        view.size = obj.size;
        view.sizeName = obj.sizeName;
        view.fileName = obj.fileName;
        // TODO: PM-23005 - Temporary field, should be removed when encrypted migration is complete
        view.key = obj.decryptedKey ? SymmetricCryptoKey.fromString(obj.decryptedKey) : undefined;
        view.encryptedKey = obj.key ? new enc_string_EncString(obj.key) : undefined;
        view._hasDecryptionError = failure;
        return view;
    }
}

;// ../../libs/common/src/autofill/constants/match-patterns.ts
const CardExpiryDateDelimiters = ["/", "-", ".", " "];
// `CardExpiryDateDelimiters` is not intended solely for regex consumption,
// so we need to format it here
const ExpiryDateDelimitersPattern = "\\" +
    CardExpiryDateDelimiters.join("\\")
        // replace space character with the regex whitespace character class
        .replace(" ", "s");
const MonthPattern = "(([1]{1}[0-2]{1})|(0?[1-9]{1}))";
// Because we're dealing with expiry dates, we assume the year will be in current or next century (as of 2024)
const match_patterns_ExpiryFullYearPattern = "2[0-1]{1}\\d{2}";
const match_patterns_DelimiterPatternExpression = new RegExp(`[${ExpiryDateDelimitersPattern}]`, "g");
const match_patterns_IrrelevantExpiryCharactersPatternExpression = new RegExp(
// "nor digits" to ensure numbers are removed from guidance pattern, which aren't covered by ^\w
`[^\\d${ExpiryDateDelimitersPattern}]`, "g");
const match_patterns_MonthPatternExpression = new RegExp(`^${MonthPattern}$`);
const match_patterns_ExpiryFullYearPatternExpression = new RegExp(`^${match_patterns_ExpiryFullYearPattern}$`);

;// ../../libs/common/src/autofill/constants/index.ts
const TYPE_CHECK = {
    FUNCTION: "function",
    NUMBER: "number",
    STRING: "string",
};
const EVENTS = {
    CHANGE: "change",
    INPUT: "input",
    KEYDOWN: "keydown",
    KEYPRESS: "keypress",
    KEYUP: "keyup",
    BLUR: "blur",
    CLICK: "click",
    FOCUS: "focus",
    FOCUSIN: "focusin",
    FOCUSOUT: "focusout",
    SCROLL: "scroll",
    RESIZE: "resize",
    DOMCONTENTLOADED: "DOMContentLoaded",
    LOAD: "load",
    MESSAGE: "message",
    VISIBILITYCHANGE: "visibilitychange",
    MOUSEENTER: "mouseenter",
    MOUSELEAVE: "mouseleave",
    MOUSEUP: "mouseup",
    MOUSEOUT: "mouseout",
    SUBMIT: "submit",
};
/**
 * HTML attributes observed by the MutationObserver for autofill form/field tracking.
 * If you need to observe a new attribute, add it here.
 */
const AUTOFILL_ATTRIBUTES = {
    ACTION: "action",
    ARIA_DESCRIBEDBY: "aria-describedby",
    ARIA_DISABLED: "aria-disabled",
    ARIA_HASPOPUP: "aria-haspopup",
    ARIA_HIDDEN: "aria-hidden",
    ARIA_LABEL: "aria-label",
    ARIA_LABELLEDBY: "aria-labelledby",
    AUTOCOMPLETE: "autocomplete",
    AUTOCOMPLETE_TYPE: "autocompletetype",
    X_AUTOCOMPLETE_TYPE: "x-autocompletetype",
    CHECKED: "checked",
    CLASS: "class",
    DATA_LABEL: "data-label",
    DATA_STRIPE: "data-stripe",
    DISABLED: "disabled",
    ID: "id",
    MAXLENGTH: "maxlength",
    METHOD: "method",
    NAME: "name",
    PLACEHOLDER: "placeholder",
    POPOVER: "popover",
    POPOVERTARGET: "popovertarget",
    POPOVERTARGETACTION: "popovertargetaction",
    READONLY: "readonly",
    REL: "rel",
    TABINDEX: "tabindex",
    TITLE: "title",
    TYPE: "type",
};
const constants_ClearClipboardDelay = {
    Never: "never",
    TenSeconds: "tenSeconds",
    TwentySeconds: "twentySeconds",
    ThirtySeconds: "thirtySeconds",
    OneMinute: "oneMinute",
    TwoMinutes: "twoMinutes",
    FiveMinutes: "fiveMinutes",
};
/* Ids for context menu items and messaging events */
const AUTOFILL_CARD_ID = "autofill-card";
const AUTOFILL_ID = "autofill";
const SHOW_AUTOFILL_BUTTON = "show-autofill-button";
const AUTOFILL_IDENTITY_ID = "autofill-identity";
const COPY_IDENTIFIER_ID = "copy-identifier";
const COPY_PASSWORD_ID = "copy-password";
const COPY_USERNAME_ID = "copy-username";
const COPY_VERIFICATION_CODE_ID = "copy-totp";
const CREATE_CARD_ID = "create-card";
const CREATE_IDENTITY_ID = "create-identity";
const CREATE_LOGIN_ID = "create-login";
const GENERATE_PASSWORD_ID = "generate-password";
const NOOP_COMMAND_SUFFIX = "noop";
const ROOT_ID = "root";
const SEPARATOR_ID = "separator";
const UPDATE_PASSWORD = "update-password";
const NOTIFICATION_BAR_LIFESPAN_MS = 150000; // 150 seconds
const AUTOFILL_OVERLAY_HANDLE_REPOSITION = "autofill-overlay-handle-reposition-event";
const AUTOFILL_OVERLAY_HANDLE_SCROLL = "autofill-overlay-handle-scroll-event";
const UPDATE_PASSKEYS_HEADINGS_ON_SCROLL = "update-passkeys-headings-on-scroll";
const AUTOFILL_TRIGGER_FORM_FIELD_SUBMIT = "autofill-trigger-form-field-submit";
const constants_AutofillOverlayVisibility = {
    Off: 0,
    OnButtonClick: 1,
    OnFieldFocus: 2,
};
const BrowserClientVendors = {
    Chrome: "Chrome",
    Opera: "Opera",
    Edge: "Edge",
    Vivaldi: "Vivaldi",
    Unknown: "Unknown",
};
const BrowserShortcutsUris = {
    Chrome: "chrome://extensions/shortcuts",
    Opera: "opera://extensions/shortcuts",
    Edge: "edge://extensions/shortcuts",
    Vivaldi: "vivaldi://extensions/shortcuts",
    Unknown: "https://bitwarden.com/help/keyboard-shortcuts",
};
const DisablePasswordManagerUris = {
    Chrome: "chrome://settings/autofill",
    Opera: "opera://settings/autofill",
    Edge: "edge://settings/passwords",
    Vivaldi: "vivaldi://settings/autofill",
    Unknown: "https://bitwarden.com/help/disable-browser-autofill/",
};
const ExtensionCommand = {
    AutofillCommand: "autofill_cmd",
    AutofillCard: "autofill_card",
    AutofillIdentity: "autofill_identity",
    AutofillLogin: "autofill_login",
    OpenAutofillOverlay: "open_autofill_overlay",
    GeneratePassword: "generate_password",
    OpenPopup: "open_popup",
    LockVault: "lock_vault",
    NoopCommand: "noop",
};
const CLEAR_NOTIFICATION_LOGIN_DATA_DURATION = (/* unused pure expression or super */ null && (60 * 1000)); // 1 minute
const MAX_DEEP_QUERY_RECURSION_DEPTH = 4;
const DEEP_QUERY_SELECTOR_COMBINATOR = ">>>";
/**
 * Field keys for targeting rules. These MUST match the `fieldKey` enum in
 * the Forms Map schema.
 */
const AutofillTargetingRuleTypes = {
    // Authentication
    username: "username",
    password: "password",
    newPassword: "newPassword",
    oneTimeCode: "oneTimeCode",
    // Name
    fullName: "fullName",
    honorificPrefix: "honorificPrefix",
    firstName: "firstName",
    middleName: "middleName",
    lastName: "lastName",
    honorificSuffix: "honorificSuffix",
    // Contact
    email: "email",
    phone: "phone",
    phoneCountryCode: "phoneCountryCode",
    phoneAreaCode: "phoneAreaCode",
    phoneLocal: "phoneLocal",
    phoneExtension: "phoneExtension",
    organization: "organization",
    // Address
    streetAddress: "streetAddress",
    addressLine1: "addressLine1",
    addressLine2: "addressLine2",
    addressLine3: "addressLine3",
    addressLevel1: "addressLevel1",
    addressLevel2: "addressLevel2",
    addressLevel3: "addressLevel3",
    addressLevel4: "addressLevel4",
    postalCode: "postalCode",
    country: "country",
    // Birthdate
    birthdate: "birthdate",
    birthdateDay: "birthdateDay",
    birthdateMonth: "birthdateMonth",
    birthdateYear: "birthdateYear",
    // Payment card
    cardholderName: "cardholderName",
    cardNumber: "cardNumber",
    cardExpirationDate: "cardExpirationDate",
    cardExpirationMonth: "cardExpirationMonth",
    cardExpirationYear: "cardExpirationYear",
    cardCvv: "cardCvv",
    cardType: "cardType",
    // Consent
    consentTerms: "consentTerms",
    consentPrivacy: "consentPrivacy",
    consentUser: "consentUser",
    // Search
    searchTerm: "searchTerm",
};
const FormPurposeCategories = {
    AccountCreation: "account-creation",
    AccountLogin: "account-login",
    AccountRecovery: "account-recovery",
    AccountUpdate: "account-update",
    Address: "address",
    Identity: "identity",
    PaymentCard: "payment-card",
    Search: "search",
    Signup: "signup",
};


;// ../../libs/common/src/autofill/utils/index.ts


/**
 * Takes a string or number value and returns a string value formatted as a valid 4-digit year
 *
 * @param {(string | number)} yearInput
 * @return {*}  {(Year | null)}
 */
function normalizeExpiryYearFormat(yearInput) {
    // The input[type="number"] is returning a number, convert it to a string
    // An empty field returns null, avoid casting `"null"` to a string
    const yearInputIsEmpty = yearInput == null || yearInput === "";
    let expirationYear = yearInputIsEmpty ? null : `${yearInput}`;
    // Exit early if year is already formatted correctly or empty
    if (yearInputIsEmpty || (expirationYear && /^[1-9]{1}\d{3}$/.test(expirationYear))) {
        return expirationYear;
    }
    expirationYear = (expirationYear || "")
        // For safety, because even input[type="number"] will allow decimals
        .replace(/[^\d]/g, "")
        // remove any leading zero padding (leave the last leading zero if it ends the string)
        .replace(/^[0]+(?=.)/, "");
    if (expirationYear === "") {
        expirationYear = null;
    }
    // given the context of payment card expiry, a year character length of 3, or over 4
    // is more likely to be a mistake than an intentional value for the far past or far future.
    if (expirationYear && expirationYear.length !== 4) {
        const paddedYear = ("00" + expirationYear).slice(-2);
        const currentCentury = `${new Date().getFullYear()}`.slice(0, 2);
        expirationYear = currentCentury + paddedYear;
    }
    return expirationYear;
}
/**
 * Takes a cipher card view and returns "true" if the month and year affirmatively indicate
 * the card is expired. Uncertain cases return "false".
 *
 * @param {CardView} cipherCard
 * @return {*}  {boolean}
 */
function isCardExpired(cipherCard) {
    if (cipherCard) {
        const { expMonth = null, expYear = null } = cipherCard;
        if (!expYear) {
            return false;
        }
        const now = new Date();
        const normalizedYear = normalizeExpiryYearFormat(expYear);
        const parsedYear = normalizedYear ? parseInt(normalizedYear, 10) : NaN;
        const expiryYearIsBeforeCurrentYear = parsedYear < now.getFullYear();
        const expiryYearIsAfterCurrentYear = parsedYear > now.getFullYear();
        // If the expiry year is before the current year, skip checking the month, since it must be expired
        if (normalizedYear && expiryYearIsBeforeCurrentYear) {
            return true;
        }
        // If the expiry year is after the current year, skip checking the month, since it cannot be expired
        if (normalizedYear && expiryYearIsAfterCurrentYear) {
            return false;
        }
        if (normalizedYear && expMonth) {
            const parsedMonthInteger = parseInt(expMonth, 10);
            const parsedMonthIsValid = parsedMonthInteger && !isNaN(parsedMonthInteger);
            // If the parsed month value is 0, we don't know when the expiry passes this year, so do not treat it as expired
            if (!parsedMonthIsValid) {
                return false;
            }
            // `Date` months are zero-indexed
            const parsedMonth = parsedMonthInteger - 1;
            // First day of the next month
            const cardExpiry = new Date(parsedYear, parsedMonth + 1, 1);
            return cardExpiry <= now;
        }
    }
    return false;
}
/**
 * Attempt to split a string into date segments on the basis of expected formats and delimiter symbols.
 *
 * @param {string} combinedExpiryValue
 * @return {*}  {string[]}
 */
function splitCombinedDateValues(combinedExpiryValue) {
    var _a;
    let sanitizedValue = combinedExpiryValue
        .replace(IrrelevantExpiryCharactersPatternExpression, "")
        .trim();
    // Do this after initial value replace to avoid identifying leading whitespace as delimiter
    const parsedDelimiter = ((_a = sanitizedValue.match(DelimiterPatternExpression)) === null || _a === void 0 ? void 0 : _a[0]) || null;
    let dateParts = [sanitizedValue];
    if (parsedDelimiter === null || parsedDelimiter === void 0 ? void 0 : parsedDelimiter.length) {
        // If the parsed delimiter is a whitespace character, assign 's' (character class) instead
        const delimiterPattern = /\s/.test(parsedDelimiter) ? "\\s" : "\\" + parsedDelimiter;
        sanitizedValue = sanitizedValue
            // Remove all other delimiter characters not identified as the delimiter
            .replace(new RegExp(`[^\\d${delimiterPattern}]`, "g"), "")
            // Also de-dupe the delimiter character
            .replace(new RegExp(`[${delimiterPattern}]{2,}`, "g"), parsedDelimiter);
        dateParts = sanitizedValue.split(parsedDelimiter);
    }
    return (dateParts
        // remove values that have no length
        .filter((splitValue) => splitValue === null || splitValue === void 0 ? void 0 : splitValue.length));
}
/**
 * Given an array of split card expiry date parts,
 * returns an array of those values ordered by year then month
 *
 * @param {string[]} splitDateInput
 * @return {*}  {([string | null, string | null])}
 */
function parseDelimitedYearMonthExpiry([firstPart, secondPart]) {
    // Conditionals here are structured to avoid unnecessary evaluations and are ordered
    // from more authoritative checks to checks yielding increasingly inferred conclusions
    // If a 4-digit value is found (when there are multiple parts), it can't be month
    if (ExpiryFullYearPatternExpression.test(firstPart)) {
        return [firstPart, secondPart];
    }
    // If a 4-digit value is found (when there are multiple parts), it can't be month
    if (ExpiryFullYearPatternExpression.test(secondPart)) {
        return [secondPart, firstPart];
    }
    // If it's a two digit value that doesn't match against month pattern, assume it's a year
    if (/\d{2}/.test(firstPart) && !MonthPatternExpression.test(firstPart)) {
        return [firstPart, secondPart];
    }
    // If it's a two digit value that doesn't match against month pattern, assume it's a year
    if (/\d{2}/.test(secondPart) && !MonthPatternExpression.test(secondPart)) {
        return [secondPart, firstPart];
    }
    // Values are too ambiguous (e.g. "12/09"). For the most part,
    // a month-looking value likely is, at the time of writing (year 2024).
    let parsedYear = firstPart;
    let parsedMonth = secondPart;
    if (MonthPatternExpression.test(firstPart)) {
        parsedYear = secondPart;
        parsedMonth = firstPart;
    }
    return [parsedYear, parsedMonth];
}
/**
 * Given a single string of integers, attempts to identify card expiry date portions within
 * and return values ordered by year then month
 *
 * @param {string} dateInput
 * @return {*}  {([string | null, string | null])}
 */
function parseNonDelimitedYearMonthExpiry(dateInput) {
    if (dateInput.length > 4) {
        // e.g.
        // "052024"
        // "202405"
        // "20245"
        // "52024"
        // If the value is over 5-characters long, it likely has a full year format in it
        const [parsedYear, parsedMonth] = dateInput
            .split(new RegExp(`(?=${ExpiryFullYearPattern})|(?<=${ExpiryFullYearPattern})`, "g"))
            .sort((current, next) => (current.length > next.length ? -1 : 1));
        return [parsedYear, parsedMonth];
    }
    if (dateInput.length === 4) {
        // e.g.
        // "0524"
        // "2405"
        // If the `sanitizedFirstPart` value is a length of 4, it must be split in half, since
        // neither a year or month will be represented with three characters
        const splitFirstPartFirstHalf = dateInput.slice(0, 2);
        const splitFirstPartSecondHalf = dateInput.slice(-2);
        let parsedYear = splitFirstPartSecondHalf;
        let parsedMonth = splitFirstPartFirstHalf;
        // If the first part doesn't match a month pattern, assume it's a year
        if (!MonthPatternExpression.test(splitFirstPartFirstHalf)) {
            parsedYear = splitFirstPartFirstHalf;
            parsedMonth = splitFirstPartSecondHalf;
        }
        return [parsedYear, parsedMonth];
    }
    // e.g.
    // "245"
    // "202"
    // "212"
    // "022"
    // "111"
    // A valid year representation here must be two characters so try to find it first.
    let parsedYear = null;
    let parsedMonth = null;
    // Split if there is a digit with a leading zero
    const splitFirstPartOnLeadingZero = dateInput.split(/(?<=0[1-9]{1})|(?=0[1-9]{1})/);
    // Assume a leading zero indicates a month in ambiguous cases (e.g. "202"), since we're
    // dealing with expiry dates and the next two-digit year with a leading zero will be 2100
    if (splitFirstPartOnLeadingZero.length > 1) {
        parsedYear = splitFirstPartOnLeadingZero[0];
        parsedMonth = splitFirstPartOnLeadingZero[1];
        if (splitFirstPartOnLeadingZero[0].startsWith("0")) {
            parsedMonth = splitFirstPartOnLeadingZero[0];
            parsedYear = splitFirstPartOnLeadingZero[1];
        }
    }
    else {
        // Here, a year has to be two-digits, and a month can't be more than one, so assume the first two digits that are greater than the current year is the year representation.
        parsedYear = dateInput.slice(0, 2);
        parsedMonth = dateInput.slice(-1);
        const currentYear = new Date().getFullYear();
        const normalizedYearFormat = normalizeExpiryYearFormat(parsedYear);
        const normalizedParsedYear = normalizedYearFormat && parseInt(normalizedYearFormat, 10);
        const normalizedExpiryYearFormat = normalizeExpiryYearFormat(dateInput.slice(-2));
        const normalizedParsedYearAlternative = normalizedExpiryYearFormat && parseInt(normalizedExpiryYearFormat, 10);
        if (normalizedParsedYear &&
            normalizedParsedYear < currentYear &&
            normalizedParsedYearAlternative &&
            normalizedParsedYearAlternative >= currentYear) {
            parsedYear = dateInput.slice(-2);
            parsedMonth = dateInput.slice(0, 1);
        }
    }
    return [parsedYear, parsedMonth];
}
/**
 * Attempt to parse year and month parts of a combined expiry date value.
 *
 * @param {string} combinedExpiryValue
 * @return {*}  {([string | null, string | null])}
 */
function parseYearMonthExpiry(combinedExpiryValue) {
    var _a, _b;
    let parsedYear = null;
    let parsedMonth = null;
    const dateParts = splitCombinedDateValues(combinedExpiryValue);
    if (dateParts.length < 1) {
        return [null, null];
    }
    const sanitizedFirstPart = ((_a = dateParts[0]) === null || _a === void 0 ? void 0 : _a.replace(IrrelevantExpiryCharactersPatternExpression, "")) || "";
    const sanitizedSecondPart = ((_b = dateParts[1]) === null || _b === void 0 ? void 0 : _b.replace(IrrelevantExpiryCharactersPatternExpression, "")) || "";
    // If there is only one date part, no delimiter was found in the passed value
    if (dateParts.length === 1) {
        const [parsedNonDelimitedYear, parsedNonDelimitedMonth] = parseNonDelimitedYearMonthExpiry(sanitizedFirstPart);
        parsedYear = parsedNonDelimitedYear;
        parsedMonth = parsedNonDelimitedMonth;
    }
    // There are multiple date parts
    else {
        const [parsedDelimitedYear, parsedDelimitedMonth] = parseDelimitedYearMonthExpiry([
            sanitizedFirstPart,
            sanitizedSecondPart,
        ]);
        parsedYear = parsedDelimitedYear;
        parsedMonth = parsedDelimitedMonth;
    }
    const normalizedParsedYear = parsedYear ? normalizeExpiryYearFormat(parsedYear) : null;
    const normalizedParsedMonth = parsedMonth === null || parsedMonth === void 0 ? void 0 : parsedMonth.replace(/^0+/, "").slice(0, 2);
    // Set "empty" values to null
    parsedYear = (normalizedParsedYear === null || normalizedParsedYear === void 0 ? void 0 : normalizedParsedYear.length) ? normalizedParsedYear : null;
    parsedMonth = (normalizedParsedMonth === null || normalizedParsedMonth === void 0 ? void 0 : normalizedParsedMonth.length) ? normalizedParsedMonth : null;
    return [parsedYear, parsedMonth];
}
/**
 * Takes a URL string and a NeverDomains object and determines if the passed URL's hostname is in `urlList`
 *
 * @param {string} url - representation of URL to check
 * @param {NeverDomains} urlList - object with hostname key names
 */
function isUrlInList(url = "", urlList = {}) {
    const urlListKeys = urlList && Object.keys(urlList);
    if (urlListKeys.length && (url === null || url === void 0 ? void 0 : url.length)) {
        let tabHostname;
        try {
            tabHostname = Utils.getHostname(url);
        }
        catch (_a) {
            // If the input was invalid, exit early and return false
            return false;
        }
        if (tabHostname) {
            return urlListKeys.some((blockedHostname) => tabHostname.endsWith(blockedHostname));
        }
    }
    return false;
}

;// ../../libs/common/src/vault/linked-field-option.decorator.ts
class LinkedMetadata {
    constructor(propertyKey, attributes) {
        this.propertyKey = propertyKey;
        this._i18nKey = attributes === null || attributes === void 0 ? void 0 : attributes.i18nKey;
        this.sortPosition = attributes.sortPosition;
    }
    get i18nKey() {
        var _a;
        return (_a = this._i18nKey) !== null && _a !== void 0 ? _a : this.propertyKey;
    }
}
/**
 * A decorator used to set metadata used by Linked custom fields. Apply it to a class property or getter to make it
 *    available as a Linked custom field option.
 * @param id - A unique value that is saved in the Field model. It is used to look up the decorated class property.
 * @param options - {@link LinkedMetadataAttributes}
 */
function linkedFieldOption(id, attributes) {
    return (prototype, propertyKey) => {
        if (prototype.linkedFieldOptions == null) {
            prototype.linkedFieldOptions = new Map();
        }
        prototype.linkedFieldOptions.set(id, new LinkedMetadata(propertyKey, attributes));
    };
}

;// ../../libs/common/src/vault/models/view/item.view.ts
class ItemView {
}

;// ../../libs/common/src/vault/models/view/card.view.ts
var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (undefined && undefined.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};




class CardView extends ItemView {
    get maskedCode() {
        return this.code != null ? "•".repeat(this.code.length) : undefined;
    }
    get maskedNumber() {
        return this.number != null ? "•".repeat(this.number.length) : undefined;
    }
    get brand() {
        return this._brand;
    }
    set brand(value) {
        this._brand = value;
        this._subTitle = undefined;
    }
    get number() {
        return this._number;
    }
    set number(value) {
        this._number = value;
        this._subTitle = undefined;
    }
    get subTitle() {
        if (this._subTitle == null) {
            this._subTitle = this.brand;
            if (this.number != null && this.number.length >= 4) {
                if (this._subTitle != null && this._subTitle !== "") {
                    this._subTitle += ", ";
                }
                else {
                    this._subTitle = "";
                }
                // Show last 5 on amex, last 4 for all others
                const count = this.number.length >= 5 && this.number.match(new RegExp("^3[47]")) != null ? 5 : 4;
                this._subTitle += "*" + this.number.substr(this.number.length - count);
            }
        }
        return this._subTitle;
    }
    get expiration() {
        const normalizedYear = this.expYear ? normalizeExpiryYearFormat(this.expYear) : undefined;
        if (!this.expMonth && !normalizedYear) {
            return undefined;
        }
        let exp = this.expMonth != null ? ("0" + this.expMonth).slice(-2) : "__";
        exp += " / " + (normalizedYear || "____");
        return exp;
    }
    static fromJSON(obj) {
        return Object.assign(new CardView(), obj);
    }
    // ref https://stackoverflow.com/a/5911300
    static getCardBrandByPatterns(cardNum) {
        if (cardNum == null || typeof cardNum !== "string" || cardNum.trim() === "") {
            return undefined;
        }
        // Visa
        let re = new RegExp("^4");
        if (cardNum.match(re) != null) {
            return "Visa";
        }
        // Mastercard
        // Updated for Mastercard 2017 BINs expansion
        if (/^(5[1-5][0-9]{14}|2(22[1-9][0-9]{12}|2[3-9][0-9]{13}|[3-6][0-9]{14}|7[0-1][0-9]{13}|720[0-9]{12}))$/.test(cardNum)) {
            return "Mastercard";
        }
        // AMEX
        re = new RegExp("^3[47]");
        if (cardNum.match(re) != null) {
            return "Amex";
        }
        // Discover
        re = new RegExp("^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65)");
        if (cardNum.match(re) != null) {
            return "Discover";
        }
        // Diners
        re = new RegExp("^36");
        if (cardNum.match(re) != null) {
            return "Diners Club";
        }
        // Diners - Carte Blanche
        re = new RegExp("^30[0-5]");
        if (cardNum.match(re) != null) {
            return "Diners Club";
        }
        // JCB
        re = new RegExp("^35(2[89]|[3-8][0-9])");
        if (cardNum.match(re) != null) {
            return "JCB";
        }
        // Visa Electron
        re = new RegExp("^(4026|417500|4508|4844|491(3|7))");
        if (cardNum.match(re) != null) {
            return "Visa";
        }
        return undefined;
    }
    /**
     * Converts an SDK CardView to a CardView.
     */
    static fromSdkCardView(obj) {
        const cardView = new CardView();
        cardView.cardholderName = obj.cardholderName;
        cardView.brand = obj.brand;
        cardView.number = obj.number;
        cardView.expMonth = obj.expMonth;
        cardView.expYear = obj.expYear;
        cardView.code = obj.code;
        return cardView;
    }
    /**
     * Converts the CardView to an SDK CardView.
     * The view implements the SdkView so we can safely return `this`
     */
    toSdkCardView() {
        return this;
    }
}
__decorate([
    linkedFieldOption(CardLinkedId.CardholderName, { sortPosition: 0 }),
    __metadata("design:type", String)
], CardView.prototype, "cardholderName", void 0);
__decorate([
    linkedFieldOption(CardLinkedId.ExpMonth, { sortPosition: 3, i18nKey: "expirationMonth" }),
    __metadata("design:type", String)
], CardView.prototype, "expMonth", void 0);
__decorate([
    linkedFieldOption(CardLinkedId.ExpYear, { sortPosition: 4, i18nKey: "expirationYear" }),
    __metadata("design:type", String)
], CardView.prototype, "expYear", void 0);
__decorate([
    linkedFieldOption(CardLinkedId.Code, { sortPosition: 5, i18nKey: "securityCode" }),
    __metadata("design:type", String)
], CardView.prototype, "code", void 0);
__decorate([
    linkedFieldOption(CardLinkedId.Brand, { sortPosition: 2 }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], CardView.prototype, "brand", null);
__decorate([
    linkedFieldOption(CardLinkedId.Number, { sortPosition: 1 }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], CardView.prototype, "number", null);

;// ../../libs/common/src/vault/models/view/fido2-credential.view.ts

class Fido2CredentialView extends ItemView {
    constructor(f) {
        var _a;
        super();
        this.discoverable = false;
        if (f == null) {
            return;
        }
        this.credentialId = f.credentialId;
        this.keyType = f.keyType;
        this.keyAlgorithm = f.keyAlgorithm;
        this.keyCurve = f.keyCurve;
        this.keyValue = f.keyValue;
        this.rpId = f.rpId;
        this.userHandle = f.userHandle;
        this.userName = f.userName;
        this.counter = f.counter;
        this.rpName = f.rpName;
        this.userDisplayName = f.userDisplayName;
        this.discoverable = (_a = f.discoverable) !== null && _a !== void 0 ? _a : false;
        this.creationDate = f.creationDate;
    }
    get subTitle() {
        return this.userDisplayName;
    }
    static fromJSON(obj) {
        const creationDate = obj.creationDate != null ? new Date(obj.creationDate) : null;
        return Object.assign(new Fido2CredentialView(), obj, {
            creationDate,
        });
    }
    /**
     * Converts the SDK Fido2CredentialView to a Fido2CredentialView.
     */
    static fromSdkFido2CredentialView(obj) {
        var _a;
        if (!obj) {
            return undefined;
        }
        return new Fido2CredentialView({
            credentialId: obj.credentialId,
            keyType: obj.keyType,
            keyAlgorithm: obj.keyAlgorithm,
            keyCurve: obj.keyCurve,
            keyValue: obj.keyValue,
            rpId: obj.rpId,
            userHandle: obj.userHandle,
            userName: obj.userName,
            counter: parseInt(obj.counter),
            rpName: obj.rpName,
            userDisplayName: obj.userDisplayName,
            discoverable: ((_a = obj.discoverable) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === "true",
            creationDate: new Date(obj.creationDate),
        });
    }
    toSdkFido2CredentialFullView() {
        var _a;
        return {
            credentialId: this.credentialId,
            keyType: this.keyType,
            keyAlgorithm: this.keyAlgorithm,
            keyCurve: this.keyCurve,
            keyValue: this.keyValue,
            rpId: this.rpId,
            userHandle: this.userHandle,
            userName: this.userName,
            counter: this.counter.toString(),
            rpName: this.rpName,
            userDisplayName: this.userDisplayName,
            discoverable: this.discoverable ? "true" : "false",
            creationDate: (_a = this.creationDate) === null || _a === void 0 ? void 0 : _a.toISOString(),
        };
    }
}

;// ../../libs/common/src/vault/models/view/field.view.ts


class FieldView {
    constructor(f) {
        this.type = FieldType.Text;
        this.newField = false; // Marks if the field is new and hasn't been saved
        this.showValue = false;
        this.showCount = false;
        if (!f) {
            return;
        }
        this.type = f.type;
        this.linkedId = f.linkedId;
    }
    get maskedValue() {
        return this.value != null ? "••••••••" : undefined;
    }
    static fromJSON(obj) {
        return Object.assign(new FieldView(), obj);
    }
    /**
     * Converts the SDK FieldView to a FieldView.
     */
    static fromSdkFieldView(obj) {
        if (!obj) {
            return undefined;
        }
        const view = new FieldView();
        view.name = obj.name;
        view.value = obj.value;
        view.type = obj.type;
        view.linkedId = obj.linkedId;
        return view;
    }
    /**
     * Converts the FieldView to an SDK FieldView.
     */
    toSdkFieldView() {
        var _a, _b, _c, _d;
        return {
            name: (_a = this.name) !== null && _a !== void 0 ? _a : undefined,
            value: (_b = this.value) !== null && _b !== void 0 ? _b : undefined,
            type: (_c = this.type) !== null && _c !== void 0 ? _c : bitwarden_wasm_internal_bg/* FieldType */.PUO.Text,
            linkedId: (_d = this.linkedId) !== null && _d !== void 0 ? _d : undefined,
        };
    }
}

;// ../../libs/common/src/vault/models/view/identity.view.ts
var identity_view_decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var identity_view_metadata = (undefined && undefined.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};




class IdentityView extends ItemView {
    constructor() {
        super();
    }
    get firstName() {
        return this._firstName;
    }
    set firstName(value) {
        this._firstName = value;
        this._subTitle = undefined;
    }
    get lastName() {
        return this._lastName;
    }
    set lastName(value) {
        this._lastName = value;
        this._subTitle = undefined;
    }
    get subTitle() {
        if (this._subTitle == null && (this.firstName != null || this.lastName != null)) {
            this._subTitle = "";
            if (this.firstName != null) {
                this._subTitle = this.firstName;
            }
            if (this.lastName != null) {
                if (this._subTitle !== "") {
                    this._subTitle += " ";
                }
                this._subTitle += this.lastName;
            }
        }
        return this._subTitle;
    }
    get fullName() {
        if (this.title != null ||
            this.firstName != null ||
            this.middleName != null ||
            this.lastName != null) {
            let name = "";
            if (!utils_Utils.isNullOrWhitespace(this.title)) {
                name += this.title + " ";
            }
            if (!utils_Utils.isNullOrWhitespace(this.firstName)) {
                name += this.firstName + " ";
            }
            if (!utils_Utils.isNullOrWhitespace(this.middleName)) {
                name += this.middleName + " ";
            }
            if (!utils_Utils.isNullOrWhitespace(this.lastName)) {
                name += this.lastName;
            }
            return name.trim();
        }
        return undefined;
    }
    get fullAddress() {
        var _a;
        let address = (_a = this.address1) !== null && _a !== void 0 ? _a : "";
        if (!utils_Utils.isNullOrWhitespace(this.address2)) {
            if (!utils_Utils.isNullOrWhitespace(address)) {
                address += ", ";
            }
            address += this.address2;
        }
        if (!utils_Utils.isNullOrWhitespace(this.address3)) {
            if (!utils_Utils.isNullOrWhitespace(address)) {
                address += ", ";
            }
            address += this.address3;
        }
        return address;
    }
    get fullAddressPart2() {
        const hasCity = !utils_Utils.isNullOrWhitespace(this.city);
        const hasState = !utils_Utils.isNullOrWhitespace(this.state);
        const hasPostalCode = !utils_Utils.isNullOrWhitespace(this.postalCode);
        if (!hasCity && !hasState && !hasPostalCode) {
            return undefined;
        }
        const city = hasCity ? this.city : "-";
        const state = this.state;
        const postalCode = hasPostalCode ? this.postalCode : "-";
        let addressPart2 = city;
        if (hasState) {
            addressPart2 += ", " + state;
        }
        addressPart2 += ", " + postalCode;
        return addressPart2;
    }
    get fullAddressForCopy() {
        let address = this.fullAddress;
        if (this.city != null || this.state != null || this.postalCode != null) {
            address += "\n" + this.fullAddressPart2;
        }
        if (this.country != null) {
            address += "\n" + this.country;
        }
        return address;
    }
    static fromJSON(obj) {
        return Object.assign(new IdentityView(), obj);
    }
    /**
     * Converts the SDK IdentityView to an IdentityView.
     */
    static fromSdkIdentityView(obj) {
        const identityView = new IdentityView();
        identityView.title = obj.title;
        identityView.firstName = obj.firstName;
        identityView.middleName = obj.middleName;
        identityView.lastName = obj.lastName;
        identityView.address1 = obj.address1;
        identityView.address2 = obj.address2;
        identityView.address3 = obj.address3;
        identityView.city = obj.city;
        identityView.state = obj.state;
        identityView.postalCode = obj.postalCode;
        identityView.country = obj.country;
        identityView.company = obj.company;
        identityView.email = obj.email;
        identityView.phone = obj.phone;
        identityView.ssn = obj.ssn;
        identityView.username = obj.username;
        identityView.passportNumber = obj.passportNumber;
        identityView.licenseNumber = obj.licenseNumber;
        return identityView;
    }
    /**
     * Converts the IdentityView to an SDK IdentityView.
     * The view implements the SdkView so we can safely return `this`
     */
    toSdkIdentityView() {
        return this;
    }
}
identity_view_decorate([
    linkedFieldOption(IdentityLinkedId.Title, { sortPosition: 0 }),
    identity_view_metadata("design:type", String)
], IdentityView.prototype, "title", void 0);
identity_view_decorate([
    linkedFieldOption(IdentityLinkedId.MiddleName, { sortPosition: 2 }),
    identity_view_metadata("design:type", String)
], IdentityView.prototype, "middleName", void 0);
identity_view_decorate([
    linkedFieldOption(IdentityLinkedId.Address1, { sortPosition: 12 }),
    identity_view_metadata("design:type", String)
], IdentityView.prototype, "address1", void 0);
identity_view_decorate([
    linkedFieldOption(IdentityLinkedId.Address2, { sortPosition: 13 }),
    identity_view_metadata("design:type", String)
], IdentityView.prototype, "address2", void 0);
identity_view_decorate([
    linkedFieldOption(IdentityLinkedId.Address3, { sortPosition: 14 }),
    identity_view_metadata("design:type", String)
], IdentityView.prototype, "address3", void 0);
identity_view_decorate([
    linkedFieldOption(IdentityLinkedId.City, { sortPosition: 15, i18nKey: "cityTown" }),
    identity_view_metadata("design:type", String)
], IdentityView.prototype, "city", void 0);
identity_view_decorate([
    linkedFieldOption(IdentityLinkedId.State, { sortPosition: 16, i18nKey: "stateProvince" }),
    identity_view_metadata("design:type", String)
], IdentityView.prototype, "state", void 0);
identity_view_decorate([
    linkedFieldOption(IdentityLinkedId.PostalCode, { sortPosition: 17, i18nKey: "zipPostalCodeLabel" }),
    identity_view_metadata("design:type", String)
], IdentityView.prototype, "postalCode", void 0);
identity_view_decorate([
    linkedFieldOption(IdentityLinkedId.Country, { sortPosition: 18 }),
    identity_view_metadata("design:type", String)
], IdentityView.prototype, "country", void 0);
identity_view_decorate([
    linkedFieldOption(IdentityLinkedId.Company, { sortPosition: 6 }),
    identity_view_metadata("design:type", String)
], IdentityView.prototype, "company", void 0);
identity_view_decorate([
    linkedFieldOption(IdentityLinkedId.Email, { sortPosition: 10 }),
    identity_view_metadata("design:type", String)
], IdentityView.prototype, "email", void 0);
identity_view_decorate([
    linkedFieldOption(IdentityLinkedId.Phone, { sortPosition: 11 }),
    identity_view_metadata("design:type", String)
], IdentityView.prototype, "phone", void 0);
identity_view_decorate([
    linkedFieldOption(IdentityLinkedId.Ssn, { sortPosition: 7 }),
    identity_view_metadata("design:type", String)
], IdentityView.prototype, "ssn", void 0);
identity_view_decorate([
    linkedFieldOption(IdentityLinkedId.Username, { sortPosition: 5 }),
    identity_view_metadata("design:type", String)
], IdentityView.prototype, "username", void 0);
identity_view_decorate([
    linkedFieldOption(IdentityLinkedId.PassportNumber, { sortPosition: 8 }),
    identity_view_metadata("design:type", String)
], IdentityView.prototype, "passportNumber", void 0);
identity_view_decorate([
    linkedFieldOption(IdentityLinkedId.LicenseNumber, { sortPosition: 9 }),
    identity_view_metadata("design:type", String)
], IdentityView.prototype, "licenseNumber", void 0);
identity_view_decorate([
    linkedFieldOption(IdentityLinkedId.FirstName, { sortPosition: 1 }),
    identity_view_metadata("design:type", String),
    identity_view_metadata("design:paramtypes", [String])
], IdentityView.prototype, "firstName", null);
identity_view_decorate([
    linkedFieldOption(IdentityLinkedId.LastName, { sortPosition: 4 }),
    identity_view_metadata("design:type", String),
    identity_view_metadata("design:paramtypes", [String])
], IdentityView.prototype, "lastName", null);
identity_view_decorate([
    linkedFieldOption(IdentityLinkedId.FullName, { sortPosition: 3 }),
    identity_view_metadata("design:type", String),
    identity_view_metadata("design:paramtypes", [])
], IdentityView.prototype, "fullName", null);

;// ../../libs/common/src/models/domain/domain-service.ts
/*
  See full documentation at:
    https://bitwarden.com/help/uri-match-detection/#match-detection-options

  Domain: "the top-level domain and second-level domain of the URI match the detected resource",
  Host: "the hostname and (if specified) port of the URI matches the detected resource",
  StartsWith: "the detected resource starts with the URI, regardless of what follows it",
  Exact: "the URI matches the detected resource exactly",
  RegularExpression: "the detected resource matches a specified regular expression",
  Never: "never offer auto-fill for the item",
*/
const domain_service_UriMatchStrategy = {
    Domain: 0,
    Host: 1,
    StartsWith: 2,
    Exact: 3,
    RegularExpression: 4,
    Never: 5,
};
/**
 * Normalizes UriMatchStrategySetting for SDK mapping.
 * @param value - The URI match strategy from user data
 * @returns Valid UriMatchType or undefined if invalid
 */
function normalizeUriMatchStrategyForSdk(value) {
    if (value == null) {
        return undefined;
    }
    switch (value) {
        case 0: // Domain
        case 1: // Host
        case 2: // StartsWith
        case 3: // Exact
        case 4: // RegularExpression
        case 5: // Never
            return value;
        default:
            return undefined;
    }
}

;// ../../libs/common/src/platform/misc/safe-urls.ts

const UrlType = Object.freeze({
    /** URI schemes stored in vault cipher items */
    CipherUri: [
        "https://",
        "http://",
        "ssh://",
        "ftp://",
        "sftp://",
        "irc://",
        "vnc://",
        // https://docs.microsoft.com/en-us/windows-server/remote/remote-desktop-services/clients/remote-desktop-uri
        "rdp://", // Legacy RDP URI scheme
        "ms-rd:", // Preferred RDP URI scheme
        "chrome://",
        "iosapp://",
        "androidapp://",
    ],
    /** URI schemes for web pages opened in an external browser */
    WebUrl: ["https://"],
});
class SafeUrls {
    static canLaunch(uri, type) {
        if (utils_Utils.isNullOrWhitespace(uri)) {
            return false;
        }
        for (let i = 0; i < type.length; i++) {
            if (uri.indexOf(type[i]) === 0) {
                return true;
            }
        }
        return false;
    }
}

;// ../../libs/common/src/vault/models/view/login-uri.view.ts



class LoginUriView {
    constructor(u) {
        if (!u) {
            return;
        }
        this.match = u.match;
    }
    get uri() {
        return this._uri;
    }
    set uri(value) {
        this._uri = value;
        this._domain = undefined;
        this._canLaunch = undefined;
    }
    get domain() {
        if (this._domain == null && this.uri != null) {
            this._domain = utils_Utils.getDomain(this.uri);
            if (this._domain === "") {
                this._domain = undefined;
            }
        }
        return this._domain;
    }
    get hostname() {
        if (this.match === domain_service_UriMatchStrategy.RegularExpression) {
            return undefined;
        }
        if (this._hostname == null && this.uri != null) {
            this._hostname = utils_Utils.getHostname(this.uri);
            if (this._hostname === "") {
                this._hostname = undefined;
            }
        }
        return this._hostname;
    }
    get host() {
        if (this.match === domain_service_UriMatchStrategy.RegularExpression) {
            return undefined;
        }
        if (this._host == null && this.uri != null) {
            this._host = utils_Utils.getHost(this.uri);
            if (this._host === "") {
                this._host = undefined;
            }
        }
        return this._host;
    }
    get hostnameOrUri() {
        return this.hostname != null ? this.hostname : this.uri;
    }
    get hostOrUri() {
        return this.host != null ? this.host : this.uri;
    }
    get isWebsite() {
        return (this.uri != null &&
            (this.uri.indexOf("http://") === 0 ||
                this.uri.indexOf("https://") === 0 ||
                (this.uri.indexOf("://") < 0 && !utils_Utils.isNullOrWhitespace(utils_Utils.getDomain(this.uri)))));
    }
    get canLaunch() {
        if (this._canLaunch != null) {
            return this._canLaunch;
        }
        if (this.uri != null && this.match !== domain_service_UriMatchStrategy.RegularExpression) {
            this._canLaunch = SafeUrls.canLaunch(this.launchUri, UrlType.CipherUri);
        }
        else {
            this._canLaunch = false;
        }
        return this._canLaunch;
    }
    get launchUri() {
        if (this.uri == null) {
            return undefined;
        }
        return this.uri.indexOf("://") < 0 && !utils_Utils.isNullOrWhitespace(utils_Utils.getDomain(this.uri))
            ? "http://" + this.uri
            : this.uri;
    }
    static fromJSON(obj) {
        return Object.assign(new LoginUriView(), obj);
    }
    /**
     * Converts a LoginUriView object from the SDK to a LoginUriView object.
     */
    static fromSdkLoginUriView(obj) {
        if (obj == null) {
            return undefined;
        }
        const view = new LoginUriView();
        view.uri = obj.uri;
        view.match = obj.match;
        return view;
    }
    /** Converts a LoginUriView object to an SDK LoginUriView object. */
    toSdkLoginUriView() {
        var _a, _b;
        return {
            uri: (_a = this.uri) !== null && _a !== void 0 ? _a : undefined,
            match: (_b = this.match) !== null && _b !== void 0 ? _b : undefined,
            uriChecksum: undefined, // SDK handles uri checksum generation internally
        };
    }
    matchesUri(targetUri, equivalentDomains, defaultUriMatch, 
    /** When present, will override the match strategy for the cipher if it is `Never` with `Domain` */
    overrideNeverMatchStrategy) {
        var _a;
        if (!this.uri || !targetUri) {
            return false;
        }
        let matchType = (_a = this.match) !== null && _a !== void 0 ? _a : defaultUriMatch;
        matchType !== null && matchType !== void 0 ? matchType : (matchType = domain_service_UriMatchStrategy.Domain);
        // Override the match strategy with `Domain` when it is `Never` and `overrideNeverMatchStrategy` is true.
        // This is useful in scenarios when the cipher should be matched to rely other information other than autofill.
        if (overrideNeverMatchStrategy && matchType === domain_service_UriMatchStrategy.Never) {
            matchType = domain_service_UriMatchStrategy.Domain;
        }
        const targetDomain = utils_Utils.getDomain(targetUri);
        const matchDomains = equivalentDomains.add(targetDomain);
        switch (matchType) {
            case domain_service_UriMatchStrategy.Domain:
                return this.matchesDomain(targetUri, matchDomains);
            case domain_service_UriMatchStrategy.Host: {
                const urlHost = utils_Utils.getHost(targetUri);
                return urlHost != null && urlHost === utils_Utils.getHost(this.uri);
            }
            case domain_service_UriMatchStrategy.Exact:
                return targetUri === this.uri;
            case domain_service_UriMatchStrategy.StartsWith:
                return targetUri.startsWith(this.uri);
            case domain_service_UriMatchStrategy.RegularExpression:
                try {
                    const regex = new RegExp(this.uri, "i");
                    return regex.test(targetUri);
                    // FIXME: Remove when updating file. Eslint update
                    // eslint-disable-next-line @typescript-eslint/no-unused-vars
                }
                catch (e) {
                    // Invalid regex
                    return false;
                }
            case domain_service_UriMatchStrategy.Never:
                return false;
            default:
                break;
        }
        return false;
    }
    matchesDomain(targetUri, matchDomains) {
        if (targetUri == null || this.domain == null || !matchDomains.has(this.domain)) {
            return false;
        }
        if (utils_Utils.DomainMatchBlacklist.has(this.domain)) {
            const domainUrlHost = utils_Utils.getHost(targetUri);
            return !utils_Utils.DomainMatchBlacklist.get(this.domain).has(domainUrlHost);
        }
        return true;
    }
}

;// ../../libs/common/src/vault/models/view/login.view.ts
var login_view_decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var login_view_metadata = (undefined && undefined.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};






class LoginView extends ItemView {
    constructor(l) {
        super();
        this.uris = [];
        this.fido2Credentials = [];
        if (!l) {
            return;
        }
        this.passwordRevisionDate = l.passwordRevisionDate;
        this.autofillOnPageLoad = l.autofillOnPageLoad;
    }
    get uri() {
        return this.hasUris ? this.uris[0].uri : undefined;
    }
    get maskedPassword() {
        return this.password != null ? "••••••••" : undefined;
    }
    get subTitle() {
        var _a;
        // if there's a passkey available, use that as a fallback
        if (utils_Utils.isNullOrEmpty(this.username) && ((_a = this.fido2Credentials) === null || _a === void 0 ? void 0 : _a.length) > 0) {
            return this.fido2Credentials[0].userName;
        }
        return this.username;
    }
    get canLaunch() {
        return this.hasUris && this.uris.some((u) => u.canLaunch);
    }
    get hasTotp() {
        return !utils_Utils.isNullOrWhitespace(this.totp);
    }
    get launchUri() {
        if (this.hasUris) {
            const uri = this.uris.find((u) => u.canLaunch);
            if (uri != null) {
                return uri.launchUri;
            }
        }
        return undefined;
    }
    get hasUris() {
        return this.uris != null && this.uris.length > 0;
    }
    get hasFido2Credentials() {
        return this.fido2Credentials != null && this.fido2Credentials.length > 0;
    }
    matchesUri(targetUri, equivalentDomains, defaultUriMatch, 
    /** When present, will override the match strategy for the cipher if it is `Never` with `Domain` */
    overrideNeverMatchStrategy) {
        if (this.uris == null) {
            return false;
        }
        return this.uris.some((uri) => uri.matchesUri(targetUri, equivalentDomains, defaultUriMatch, overrideNeverMatchStrategy));
    }
    static fromJSON(obj) {
        var _a, _b, _c, _d;
        if (obj == undefined) {
            return new LoginView();
        }
        const loginView = Object.assign(new LoginView(), obj);
        loginView.passwordRevisionDate =
            obj.passwordRevisionDate == null ? undefined : new Date(obj.passwordRevisionDate);
        loginView.uris = (_b = (_a = obj.uris) === null || _a === void 0 ? void 0 : _a.map((uri) => LoginUriView.fromJSON(uri))) !== null && _b !== void 0 ? _b : [];
        loginView.fido2Credentials =
            (_d = (_c = obj.fido2Credentials) === null || _c === void 0 ? void 0 : _c.map((key) => Fido2CredentialView.fromJSON(key))) !== null && _d !== void 0 ? _d : [];
        return loginView;
    }
    /**
     * Converts the SDK LoginView to a LoginView.
     *
     * Note: FIDO2 credentials remain encrypted at this stage.
     * Unlike other fields that are decrypted as part of the LoginView, the SDK maintains
     * the FIDO2 credentials in encrypted form. We can decrypt them later using a separate
     * call to client.vault().ciphers().decrypt_fido2_credentials().
     */
    static fromSdkLoginView(obj) {
        var _a;
        const loginView = new LoginView();
        loginView.username = obj.username;
        loginView.password = obj.password;
        loginView.passwordRevisionDate =
            obj.passwordRevisionDate == null ? undefined : new Date(obj.passwordRevisionDate);
        loginView.totp = obj.totp;
        loginView.autofillOnPageLoad = obj.autofillOnPageLoad;
        loginView.uris =
            ((_a = obj.uris) === null || _a === void 0 ? void 0 : _a.filter((uri) => uri.uri != null && uri.uri !== "").map((uri) => LoginUriView.fromSdkLoginUriView(uri))) || [];
        // FIDO2 credentials are not decrypted here, they remain encrypted
        loginView.fido2Credentials = [];
        return loginView;
    }
    /**
     * Converts the LoginView to an SDK LoginView.
     *
     * Note: FIDO2 credentials remain encrypted in the SDK view so they are not included here.
     */
    toSdkLoginView() {
        var _a, _b, _c;
        return {
            username: this.username,
            password: this.password,
            passwordRevisionDate: (_a = this.passwordRevisionDate) === null || _a === void 0 ? void 0 : _a.toISOString(),
            totp: this.hasTotp ? this.totp : undefined,
            autofillOnPageLoad: (_b = this.autofillOnPageLoad) !== null && _b !== void 0 ? _b : undefined,
            uris: (_c = this.uris) === null || _c === void 0 ? void 0 : _c.map((uri) => uri.toSdkLoginUriView()),
            fido2Credentials: undefined, // FIDO2 credentials are handled separately and remain encrypted
        };
    }
}
login_view_decorate([
    linkedFieldOption(LoginLinkedId.Username, { sortPosition: 0 }),
    login_view_metadata("design:type", String)
], LoginView.prototype, "username", void 0);
login_view_decorate([
    linkedFieldOption(LoginLinkedId.Password, { sortPosition: 1 }),
    login_view_metadata("design:type", String)
], LoginView.prototype, "password", void 0);

;// ../../libs/common/src/vault/models/view/password-history.view.ts
class PasswordHistoryView {
    constructor(ph) {
        this.password = null;
        this.lastUsedDate = null;
        if (!ph) {
            return;
        }
        this.lastUsedDate = ph.lastUsedDate;
    }
    static fromJSON(obj) {
        const lastUsedDate = obj.lastUsedDate == null ? null : new Date(obj.lastUsedDate);
        return Object.assign(new PasswordHistoryView(), obj, {
            lastUsedDate: lastUsedDate,
        });
    }
    /**
     * Converts the SDK PasswordHistoryView to a PasswordHistoryView.
     */
    static fromSdkPasswordHistoryView(obj) {
        if (!obj) {
            return undefined;
        }
        const view = new PasswordHistoryView();
        view.password = obj.password;
        view.lastUsedDate = obj.lastUsedDate == null ? null : new Date(obj.lastUsedDate);
        return view;
    }
    /**
     * Converts the PasswordHistoryView to an SDK PasswordHistoryView.
     */
    toSdkPasswordHistoryView() {
        var _a;
        return {
            password: (_a = this.password) !== null && _a !== void 0 ? _a : "",
            lastUsedDate: this.lastUsedDate.toISOString(),
        };
    }
}

;// ../../libs/common/src/vault/models/view/secure-note.view.ts


class SecureNoteView extends ItemView {
    constructor(n) {
        super();
        this.type = SecureNoteType.Generic;
        if (!n) {
            return;
        }
        this.type = n.type;
    }
    get subTitle() {
        return undefined;
    }
    static fromJSON(obj) {
        return Object.assign(new SecureNoteView(), obj);
    }
    /**
     * Converts the SDK SecureNoteView to a SecureNoteView.
     */
    static fromSdkSecureNoteView(obj) {
        const secureNoteView = new SecureNoteView();
        secureNoteView.type = obj.type;
        return secureNoteView;
    }
    /**
     * Converts the SecureNoteView to an SDK SecureNoteView.
     * The view implements the SdkView so we can safely return `this`
     */
    toSdkSecureNoteView() {
        return this;
    }
}

;// ../../libs/common/src/vault/models/view/ssh-key.view.ts

class SshKeyView extends ItemView {
    get maskedPrivateKey() {
        if (!this.privateKey || this.privateKey.length === 0) {
            return "";
        }
        let lines = this.privateKey.split("\n").filter((l) => l.trim() !== "");
        lines = lines.map((l, i) => {
            if (i === 0 || i === lines.length - 1) {
                return l;
            }
            return this.maskLine(l);
        });
        return lines.join("\n");
    }
    maskLine(line) {
        return "•".repeat(32);
    }
    get subTitle() {
        return this.keyFingerprint;
    }
    static fromJSON(obj) {
        return Object.assign(new SshKeyView(), obj);
    }
    /**
     * Converts the SDK SshKeyView to a SshKeyView.
     */
    static fromSdkSshKeyView(obj) {
        const sshKeyView = new SshKeyView();
        sshKeyView.privateKey = obj.privateKey;
        sshKeyView.publicKey = obj.publicKey;
        sshKeyView.keyFingerprint = obj.fingerprint;
        return sshKeyView;
    }
    /**
     * Converts the SshKeyView to an SDK SshKeyView.
     */
    toSdkSshKeyView() {
        return {
            privateKey: this.privateKey,
            publicKey: this.publicKey,
            fingerprint: this.keyFingerprint,
        };
    }
}

;// ../../libs/common/src/vault/models/view/cipher.view.ts
















class CipherView {
    constructor(c) {
        var _a;
        this.initializerKey = InitializerKey.CipherView;
        this.id = "";
        this.name = "";
        this.type = CipherType.Login;
        this.favorite = false;
        this.organizationUseTotp = false;
        this.permissions = new CipherPermissionsApi();
        this.edit = false;
        this.viewPassword = true;
        this.login = new LoginView();
        this.identity = new IdentityView();
        this.card = new CardView();
        this.secureNote = new SecureNoteView();
        this.sshKey = new SshKeyView();
        this.attachments = [];
        this.fields = [];
        this.passwordHistory = [];
        this.collectionIds = [];
        this.reprompt = CipherRepromptType.None;
        /**
         * Flag to indicate if the cipher decryption failed.
         */
        this.decryptionFailure = false;
        if (!c) {
            this.creationDate = this.revisionDate = new Date();
            return;
        }
        this.id = c.id;
        this.organizationId = c.organizationId;
        this.folderId = c.folderId;
        this.favorite = c.favorite;
        this.organizationUseTotp = c.organizationUseTotp;
        this.edit = c.edit;
        this.viewPassword = c.viewPassword;
        this.permissions = c.permissions;
        this.type = c.type;
        this.localData = c.localData;
        this.collectionIds = c.collectionIds;
        this.revisionDate = c.revisionDate;
        this.creationDate = c.creationDate;
        this.deletedDate = c.deletedDate;
        this.archivedDate = c.archivedDate;
        // Old locally stored ciphers might have reprompt == null. If so set it to None.
        this.reprompt = (_a = c.reprompt) !== null && _a !== void 0 ? _a : CipherRepromptType.None;
        this.key = c.key;
    }
    get item() {
        switch (this.type) {
            case CipherType.Login:
                return this.login;
            case CipherType.SecureNote:
                return this.secureNote;
            case CipherType.Card:
                return this.card;
            case CipherType.Identity:
                return this.identity;
            case CipherType.SshKey:
                return this.sshKey;
            default:
                break;
        }
        return undefined;
    }
    get subTitle() {
        var _a;
        return (_a = this.item) === null || _a === void 0 ? void 0 : _a.subTitle;
    }
    get canBeArchived() {
        return !this.isDeleted && !this.isArchived;
    }
    get hasPasswordHistory() {
        return this.passwordHistory && this.passwordHistory.length > 0;
    }
    get hasLoginPassword() {
        var _a;
        return (this.type === CipherType.Login && ((_a = this.login) === null || _a === void 0 ? void 0 : _a.password) != null && this.login.password !== "");
    }
    get hasAttachments() {
        return !!this.attachments && this.attachments.length > 0;
    }
    get hasOldAttachments() {
        if (this.hasAttachments) {
            for (let i = 0; i < this.attachments.length; i++) {
                if (this.attachments[i].key == null && this.attachments[i].encryptedKey == null) {
                    return true;
                }
            }
        }
        return false;
    }
    get hasFields() {
        return this.fields && this.fields.length > 0;
    }
    get passwordRevisionDisplayDate() {
        if (this.type !== CipherType.Login || this.login == null) {
            return undefined;
        }
        else if (this.login.password == null || this.login.password === "") {
            return undefined;
        }
        return this.login.passwordRevisionDate;
    }
    get isDeleted() {
        return this.deletedDate != null;
    }
    get isArchived() {
        return this.archivedDate != null;
    }
    get linkedFieldOptions() {
        var _a;
        return (_a = this.item) === null || _a === void 0 ? void 0 : _a.linkedFieldOptions;
    }
    get isUnassigned() {
        return (this.organizationId != null && (this.collectionIds == null || this.collectionIds.length === 0));
    }
    get canAssignToCollections() {
        if (this.organizationId == null) {
            return true;
        }
        return this.edit && this.viewPassword;
    }
    /**
     * Determines if the cipher can be launched in a new browser tab.
     */
    get canLaunch() {
        return this.type === CipherType.Login && this.login.canLaunch;
    }
    linkedFieldValue(id) {
        var _a;
        const linkedFieldOption = (_a = this.linkedFieldOptions) === null || _a === void 0 ? void 0 : _a.get(id);
        const item = this.item;
        if (linkedFieldOption == null || item == null) {
            return undefined;
        }
        return item[linkedFieldOption.propertyKey];
    }
    // This is used as a marker to indicate that the cipher view object still has its prototype
    toJSON() {
        return this;
    }
    static fromJSON(obj) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
        if (obj == null) {
            return null;
        }
        const view = new CipherView();
        view.type = (_a = obj.type) !== null && _a !== void 0 ? _a : CipherType.Login;
        view.id = (_b = obj.id) !== null && _b !== void 0 ? _b : "";
        view.organizationId = (_c = obj.organizationId) !== null && _c !== void 0 ? _c : undefined;
        view.folderId = (_d = obj.folderId) !== null && _d !== void 0 ? _d : undefined;
        view.collectionIds = (_e = obj.collectionIds) !== null && _e !== void 0 ? _e : [];
        view.name = (_f = obj.name) !== null && _f !== void 0 ? _f : "";
        view.notes = obj.notes;
        view.edit = (_g = obj.edit) !== null && _g !== void 0 ? _g : false;
        view.viewPassword = (_h = obj.viewPassword) !== null && _h !== void 0 ? _h : true;
        view.favorite = (_j = obj.favorite) !== null && _j !== void 0 ? _j : false;
        view.organizationUseTotp = (_k = obj.organizationUseTotp) !== null && _k !== void 0 ? _k : false;
        view.localData = obj.localData ? obj.localData : undefined;
        view.permissions = obj.permissions ? CipherPermissionsApi.fromJSON(obj.permissions) : undefined;
        view.reprompt = (_l = obj.reprompt) !== null && _l !== void 0 ? _l : CipherRepromptType.None;
        view.decryptionFailure = (_m = obj.decryptionFailure) !== null && _m !== void 0 ? _m : false;
        if (obj.creationDate) {
            view.creationDate = new Date(obj.creationDate);
        }
        if (obj.revisionDate) {
            view.revisionDate = new Date(obj.revisionDate);
        }
        view.deletedDate = obj.deletedDate == null ? undefined : new Date(obj.deletedDate);
        view.archivedDate = obj.archivedDate == null ? undefined : new Date(obj.archivedDate);
        view.attachments = (_p = (_o = obj.attachments) === null || _o === void 0 ? void 0 : _o.map((a) => AttachmentView.fromJSON(a))) !== null && _p !== void 0 ? _p : [];
        view.fields = (_r = (_q = obj.fields) === null || _q === void 0 ? void 0 : _q.map((f) => FieldView.fromJSON(f))) !== null && _r !== void 0 ? _r : [];
        view.passwordHistory =
            (_t = (_s = obj.passwordHistory) === null || _s === void 0 ? void 0 : _s.map((ph) => PasswordHistoryView.fromJSON(ph))) !== null && _t !== void 0 ? _t : [];
        if (obj.key != null) {
            let key;
            if (typeof obj.key === "string") {
                // If the key is a string, we need to parse it as EncString
                key = enc_string_EncString.fromJSON(obj.key);
            }
            else if (obj.key instanceof enc_string_EncString) {
                // If the key is already an EncString instance, we can use it directly
                key = obj.key;
            }
            view.key = key;
        }
        switch (obj.type) {
            case CipherType.Card:
                view.card = CardView.fromJSON(obj.card);
                break;
            case CipherType.Identity:
                view.identity = IdentityView.fromJSON(obj.identity);
                break;
            case CipherType.Login:
                view.login = LoginView.fromJSON(obj.login);
                break;
            case CipherType.SecureNote:
                view.secureNote = SecureNoteView.fromJSON(obj.secureNote);
                break;
            case CipherType.SshKey:
                view.sshKey = SshKeyView.fromJSON(obj.sshKey);
                break;
            default:
                break;
        }
        return view;
    }
    /**
     * Creates a CipherView from the SDK CipherView.
     */
    static fromSdkCipherView(obj, sdk) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
        if (obj == null) {
            return undefined;
        }
        const attachments = (_b = (_a = obj.attachments) === null || _a === void 0 ? void 0 : _a.map((a) => AttachmentView.fromSdkAttachmentView(a))) !== null && _b !== void 0 ? _b : [];
        if ((_c = obj.attachmentDecryptionFailures) === null || _c === void 0 ? void 0 : _c.length) {
            obj.attachmentDecryptionFailures.forEach((attachment) => {
                const attachmentView = AttachmentView.fromSdkAttachmentView(attachment, true);
                if (attachmentView) {
                    attachments.push(attachmentView);
                }
            });
        }
        const cipherView = new CipherView();
        cipherView.id = uuidAsString(obj.id);
        cipherView.organizationId = uuidAsString(obj.organizationId);
        cipherView.folderId = uuidAsString(obj.folderId);
        cipherView.name = obj.name;
        cipherView.notes = obj.notes;
        cipherView.type = obj.type;
        cipherView.favorite = obj.favorite;
        cipherView.organizationUseTotp = obj.organizationUseTotp;
        cipherView.permissions = obj.permissions
            ? CipherPermissionsApi.fromSdkCipherPermissions(obj.permissions)
            : undefined;
        cipherView.edit = obj.edit;
        cipherView.viewPassword = obj.viewPassword;
        cipherView.localData = fromSdkLocalData(obj.localData);
        cipherView.attachments = attachments;
        cipherView.fields = (_e = (_d = obj.fields) === null || _d === void 0 ? void 0 : _d.map((f) => FieldView.fromSdkFieldView(f))) !== null && _e !== void 0 ? _e : [];
        cipherView.passwordHistory =
            (_g = (_f = obj.passwordHistory) === null || _f === void 0 ? void 0 : _f.map((ph) => PasswordHistoryView.fromSdkPasswordHistoryView(ph))) !== null && _g !== void 0 ? _g : [];
        cipherView.collectionIds = (_j = (_h = obj.collectionIds) === null || _h === void 0 ? void 0 : _h.map((i) => uuidAsString(i))) !== null && _j !== void 0 ? _j : [];
        cipherView.revisionDate = new Date(obj.revisionDate);
        cipherView.creationDate = new Date(obj.creationDate);
        cipherView.deletedDate = obj.deletedDate == null ? undefined : new Date(obj.deletedDate);
        cipherView.archivedDate = obj.archivedDate == null ? undefined : new Date(obj.archivedDate);
        cipherView.reprompt = (_k = obj.reprompt) !== null && _k !== void 0 ? _k : CipherRepromptType.None;
        cipherView.key = obj.key ? enc_string_EncString.fromJSON(obj.key) : undefined;
        switch (obj.type) {
            case CipherType.Card:
                cipherView.card = obj.card ? CardView.fromSdkCardView(obj.card) : new CardView();
                break;
            case CipherType.Identity:
                cipherView.identity = obj.identity
                    ? IdentityView.fromSdkIdentityView(obj.identity)
                    : new IdentityView();
                break;
            case CipherType.Login:
                cipherView.login = obj.login ? LoginView.fromSdkLoginView(obj.login) : new LoginView();
                if (sdk && ((_m = (_l = obj.login) === null || _l === void 0 ? void 0 : _l.fido2Credentials) === null || _m === void 0 ? void 0 : _m.length)) {
                    const fido2CredentialViews = sdk.decrypt_fido2_credentials(obj);
                    const decryptedKeyValue = sdk.decrypt_fido2_private_key(obj);
                    cipherView.login.fido2Credentials = fido2CredentialViews
                        .map((cred) => {
                        const view = Fido2CredentialView.fromSdkFido2CredentialView(cred);
                        if (view) {
                            view.keyValue = decryptedKeyValue;
                        }
                        return view;
                    })
                        .filter((cred) => !!cred);
                }
                break;
            case CipherType.SecureNote:
                cipherView.secureNote = obj.secureNote
                    ? SecureNoteView.fromSdkSecureNoteView(obj.secureNote)
                    : new SecureNoteView();
                break;
            case CipherType.SshKey:
                cipherView.sshKey = obj.sshKey
                    ? SshKeyView.fromSdkSshKeyView(obj.sshKey)
                    : new SshKeyView();
                break;
            default:
                break;
        }
        return cipherView;
    }
    /**
     * Maps CipherView to an SDK CipherCreateRequest
     *
     * @returns {CipherCreateRequest} The SDK cipher create request object
     */
    toSdkCreateCipherRequest(sdk) {
        var _a, _b, _c, _d, _e;
        const sdkCipherCreateRequest = {
            organizationId: this.organizationId ? asUuid(this.organizationId) : undefined,
            collectionIds: this.collectionIds ? this.collectionIds.map((i) => asUuid(i)) : [],
            folderId: this.folderId ? asUuid(this.folderId) : undefined,
            name: (_a = this.name) !== null && _a !== void 0 ? _a : "",
            notes: this.notes,
            favorite: (_b = this.favorite) !== null && _b !== void 0 ? _b : false,
            reprompt: (_c = this.reprompt) !== null && _c !== void 0 ? _c : CipherRepromptType.None,
            fields: (_d = this.fields) === null || _d === void 0 ? void 0 : _d.map((f) => f.toSdkFieldView()),
            type: this.getSdkCipherViewType(),
        };
        // If the cipher has FIDO2 credentials, we need to set them on the SDK create request
        // separately due to restrictions in how the SDK handles them.
        if (this.type === CipherType.Login && ((_e = this.login) === null || _e === void 0 ? void 0 : _e.hasFido2Credentials)) {
            const sdkCipherView = this.toSdkCipherView(sdk);
            sdkCipherCreateRequest.type = { login: sdkCipherView.login };
        }
        return sdkCipherCreateRequest;
    }
    /**
     * Maps CipherView to an SDK CipherEditRequest
     *
     * @returns {CipherEditRequest} The SDK cipher edit request object
     */
    toSdkUpdateCipherRequest(sdk) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j;
        const sdkCipherEditRequest = {
            id: asUuid(this.id),
            organizationId: this.organizationId ? asUuid(this.organizationId) : undefined,
            folderId: this.folderId ? asUuid(this.folderId) : undefined,
            name: (_a = this.name) !== null && _a !== void 0 ? _a : "",
            notes: this.notes,
            favorite: (_b = this.favorite) !== null && _b !== void 0 ? _b : false,
            reprompt: (_c = this.reprompt) !== null && _c !== void 0 ? _c : CipherRepromptType.None,
            fields: (_d = this.fields) === null || _d === void 0 ? void 0 : _d.map((f) => f.toSdkFieldView()),
            type: this.getSdkCipherViewType(),
            revisionDate: (_e = this.revisionDate) === null || _e === void 0 ? void 0 : _e.toISOString(),
            archivedDate: (_f = this.archivedDate) === null || _f === void 0 ? void 0 : _f.toISOString(),
            attachments: (_g = this.attachments) === null || _g === void 0 ? void 0 : _g.map((a) => a.toSdkAttachmentView()),
            key: (_h = this.key) === null || _h === void 0 ? void 0 : _h.toSdk(),
        };
        // If the cipher has FIDO2 credentials, we need to set them on the SDK edit request
        // separately due to restrictions in how the SDK handles them.
        if (this.type === CipherType.Login && ((_j = this.login) === null || _j === void 0 ? void 0 : _j.hasFido2Credentials)) {
            const sdkCipherView = this.toSdkCipherView(sdk);
            sdkCipherEditRequest.type = { login: sdkCipherView.login };
        }
        return sdkCipherEditRequest;
    }
    /**
     * Returns the SDK CipherViewType object for the cipher.
     *
     * @returns {CipherViewType} The SDK CipherViewType for the cipher.t
     */
    getSdkCipherViewType() {
        var _a, _b, _c, _d, _e;
        let viewType;
        switch (this.type) {
            case CipherType.Card:
                viewType = { card: (_a = this.card) === null || _a === void 0 ? void 0 : _a.toSdkCardView() };
                break;
            case CipherType.Identity:
                viewType = { identity: (_b = this.identity) === null || _b === void 0 ? void 0 : _b.toSdkIdentityView() };
                break;
            case CipherType.Login:
                viewType = { login: (_c = this.login) === null || _c === void 0 ? void 0 : _c.toSdkLoginView() };
                break;
            case CipherType.SecureNote:
                viewType = { secureNote: (_d = this.secureNote) === null || _d === void 0 ? void 0 : _d.toSdkSecureNoteView() };
                break;
            case CipherType.SshKey:
                viewType = { sshKey: (_e = this.sshKey) === null || _e === void 0 ? void 0 : _e.toSdkSshKeyView() };
                break;
            default:
                viewType = {
                    // Default to empty login - should not be valid code path.
                    login: new LoginView().toSdkLoginView(),
                };
                break;
        }
        return viewType;
    }
    /**
     * Maps CipherView to SdkCipherView
     *
     * If `sdk` parameter is provided, it will set the FIDO2 credentials on the SDK view,
     * since they remain encrypted and are not included in the standard mapping.
     *
     * If sdk is not provided, the caller is responsible for handling the FIDO2 credentials
     * on the SDK view separately.
     *
     * @returns {SdkCipherView} The SDK cipher view object
     */
    toSdkCipherView(sdk) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
        let sdkCipherView = {
            id: this.id ? asUuid(this.id) : undefined,
            organizationId: this.organizationId ? asUuid(this.organizationId) : undefined,
            folderId: this.folderId ? asUuid(this.folderId) : undefined,
            name: (_a = this.name) !== null && _a !== void 0 ? _a : "",
            notes: this.notes,
            type: (_b = this.type) !== null && _b !== void 0 ? _b : CipherType.Login,
            favorite: (_c = this.favorite) !== null && _c !== void 0 ? _c : false,
            organizationUseTotp: (_d = this.organizationUseTotp) !== null && _d !== void 0 ? _d : false,
            permissions: (_e = this.permissions) === null || _e === void 0 ? void 0 : _e.toSdkCipherPermissions(),
            edit: (_f = this.edit) !== null && _f !== void 0 ? _f : true,
            viewPassword: (_g = this.viewPassword) !== null && _g !== void 0 ? _g : true,
            localData: toSdkLocalData(this.localData),
            attachments: (_h = this.attachments) === null || _h === void 0 ? void 0 : _h.map((a) => a.toSdkAttachmentView()),
            fields: (_j = this.fields) === null || _j === void 0 ? void 0 : _j.map((f) => f.toSdkFieldView()),
            passwordHistory: (_k = this.passwordHistory) === null || _k === void 0 ? void 0 : _k.map((ph) => ph.toSdkPasswordHistoryView()),
            collectionIds: (_m = (_l = this.collectionIds) === null || _l === void 0 ? void 0 : _l.map((i) => asUuid(i))) !== null && _m !== void 0 ? _m : [],
            // Revision and creation dates are non-nullable in SDKCipherView
            revisionDate: ((_o = this.revisionDate) !== null && _o !== void 0 ? _o : new Date()).toISOString(),
            creationDate: ((_p = this.creationDate) !== null && _p !== void 0 ? _p : new Date()).toISOString(),
            deletedDate: (_q = this.deletedDate) === null || _q === void 0 ? void 0 : _q.toISOString(),
            archivedDate: (_r = this.archivedDate) === null || _r === void 0 ? void 0 : _r.toISOString(),
            reprompt: (_s = this.reprompt) !== null && _s !== void 0 ? _s : CipherRepromptType.None,
            key: (_t = this.key) === null || _t === void 0 ? void 0 : _t.toSdk(),
            // Cipher type specific properties are set in the switch statement below
            // CipherView initializes each with default constructors (undefined values)
            // The SDK does not expect those undefined values and will throw exceptions
            login: undefined,
            card: undefined,
            identity: undefined,
            secureNote: undefined,
            sshKey: undefined,
        };
        switch (this.type) {
            case CipherType.Card:
                sdkCipherView.card = (_u = this.card) === null || _u === void 0 ? void 0 : _u.toSdkCardView();
                break;
            case CipherType.Identity:
                sdkCipherView.identity = (_v = this.identity) === null || _v === void 0 ? void 0 : _v.toSdkIdentityView();
                break;
            case CipherType.Login:
                sdkCipherView.login = (_w = this.login) === null || _w === void 0 ? void 0 : _w.toSdkLoginView();
                break;
            case CipherType.SecureNote:
                sdkCipherView.secureNote = (_x = this.secureNote) === null || _x === void 0 ? void 0 : _x.toSdkSecureNoteView();
                break;
            case CipherType.SshKey:
                sdkCipherView.sshKey = (_y = this.sshKey) === null || _y === void 0 ? void 0 : _y.toSdkSshKeyView();
                break;
            default:
                break;
        }
        // If the cipher has FIDO2 credentials, we need to set them on the SDK view separately since they remain encrypted.
        if (sdk && this.type === CipherType.Login && ((_z = this.login) === null || _z === void 0 ? void 0 : _z.hasFido2Credentials)) {
            const fido2Credentials = this.login.fido2Credentials.map((cred) => cred.toSdkFido2CredentialFullView());
            sdkCipherView = sdk.set_fido2_credentials(sdkCipherView, fido2Credentials);
        }
        return sdkCipherView;
    }
}

;// ../../libs/common/src/vault/models/domain/attachment.ts
var attachment_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};





class Attachment extends Domain {
    constructor(obj) {
        super();
        if (obj == null) {
            return;
        }
        this.id = obj.id;
        this.url = obj.url;
        this.size = obj.size;
        this.sizeName = obj.sizeName;
        this.fileName = conditionalEncString(obj.fileName);
        this.key = conditionalEncString(obj.key);
    }
    decrypt(decryptionKey_1) {
        return attachment_awaiter(this, arguments, void 0, function* (decryptionKey, context = "No Cipher Context") {
            const view = yield this.decryptObj(this, new AttachmentView(this), ["fileName"], decryptionKey, "DomainType: Attachment; " + context);
            if (this.key != null) {
                view.key = yield this.decryptAttachmentKey(decryptionKey);
                view.encryptedKey = this.key; // Keep the encrypted key for the view
                // When the attachment key couldn't be decrypted, mark a decryption error
                // The file won't be able to be downloaded in these cases
                if (!view.key) {
                    view.hasDecryptionError = true;
                }
            }
            return view;
        });
    }
    decryptAttachmentKey(decryptionKey) {
        return attachment_awaiter(this, void 0, void 0, function* () {
            try {
                if (this.key == null) {
                    return undefined;
                }
                const encryptService = utils_Utils.getContainerService().getEncryptService();
                const decValue = yield encryptService.unwrapSymmetricKey(this.key, decryptionKey);
                return decValue;
            }
            catch (e) {
                // eslint-disable-next-line no-console
                console.error("[Attachment] Error decrypting attachment", e);
                return undefined;
            }
        });
    }
    toAttachmentData() {
        const a = new AttachmentData();
        if (this.size != null) {
            a.size = this.size;
        }
        this.buildDataModel(this, a, {
            id: null,
            url: null,
            sizeName: null,
            fileName: null,
            key: null,
        }, ["id", "url", "sizeName"]);
        return a;
    }
    static fromJSON(obj) {
        if (obj == null) {
            return undefined;
        }
        const attachment = new Attachment();
        attachment.id = obj.id;
        attachment.url = obj.url;
        attachment.size = obj.size;
        attachment.sizeName = obj.sizeName;
        attachment.key = encStringFrom(obj.key);
        attachment.fileName = encStringFrom(obj.fileName);
        return attachment;
    }
    /**
     * Maps to SDK Attachment
     *
     * @returns {SdkAttachment} - The SDK Attachment object
     */
    toSdkAttachment() {
        var _a, _b;
        return {
            id: this.id,
            url: this.url,
            size: this.size,
            sizeName: this.sizeName,
            fileName: (_a = this.fileName) === null || _a === void 0 ? void 0 : _a.toSdk(),
            key: (_b = this.key) === null || _b === void 0 ? void 0 : _b.toSdk(),
        };
    }
    /**
     * Maps an SDK Attachment object to an Attachment
     * @param obj - The SDK attachment object
     */
    static fromSdkAttachment(obj) {
        if (!obj) {
            return undefined;
        }
        const attachment = new Attachment();
        attachment.id = obj.id;
        attachment.url = obj.url;
        attachment.size = obj.size;
        attachment.sizeName = obj.sizeName;
        attachment.fileName = encStringFrom(obj.fileName);
        attachment.key = encStringFrom(obj.key);
        return attachment;
    }
}

;// ../../libs/common/src/vault/models/domain/card.ts
var card_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};




class Card extends Domain {
    constructor(obj) {
        super();
        if (obj == null) {
            return;
        }
        this.cardholderName = conditionalEncString(obj.cardholderName);
        this.brand = conditionalEncString(obj.brand);
        this.number = conditionalEncString(obj.number);
        this.expMonth = conditionalEncString(obj.expMonth);
        this.expYear = conditionalEncString(obj.expYear);
        this.code = conditionalEncString(obj.code);
    }
    decrypt(encKey_1) {
        return card_awaiter(this, arguments, void 0, function* (encKey, context = "No Cipher Context") {
            return this.decryptObj(this, new CardView(), ["cardholderName", "brand", "number", "expMonth", "expYear", "code"], encKey, "DomainType: Card; " + context);
        });
    }
    toCardData() {
        const c = new CardData();
        this.buildDataModel(this, c, {
            cardholderName: null,
            brand: null,
            number: null,
            expMonth: null,
            expYear: null,
            code: null,
        });
        return c;
    }
    static fromJSON(obj) {
        if (obj == null) {
            return undefined;
        }
        const card = new Card();
        card.cardholderName = encStringFrom(obj.cardholderName);
        card.brand = encStringFrom(obj.brand);
        card.number = encStringFrom(obj.number);
        card.expMonth = encStringFrom(obj.expMonth);
        card.expYear = encStringFrom(obj.expYear);
        card.code = encStringFrom(obj.code);
        return card;
    }
    /**
     *  Maps Card to SDK format.
     *
     * @returns {SdkCard} The SDK card object.
     */
    toSdkCard() {
        var _a, _b, _c, _d, _e, _f;
        return {
            cardholderName: (_a = this.cardholderName) === null || _a === void 0 ? void 0 : _a.toSdk(),
            brand: (_b = this.brand) === null || _b === void 0 ? void 0 : _b.toSdk(),
            number: (_c = this.number) === null || _c === void 0 ? void 0 : _c.toSdk(),
            expMonth: (_d = this.expMonth) === null || _d === void 0 ? void 0 : _d.toSdk(),
            expYear: (_e = this.expYear) === null || _e === void 0 ? void 0 : _e.toSdk(),
            code: (_f = this.code) === null || _f === void 0 ? void 0 : _f.toSdk(),
        };
    }
    /**
     * Maps an SDK Card object to a Card
     * @param obj - The SDK Card object
     */
    static fromSdkCard(obj) {
        if (!obj) {
            return undefined;
        }
        const card = new Card();
        card.cardholderName = encStringFrom(obj.cardholderName);
        card.brand = encStringFrom(obj.brand);
        card.number = encStringFrom(obj.number);
        card.expMonth = encStringFrom(obj.expMonth);
        card.expYear = encStringFrom(obj.expYear);
        card.code = encStringFrom(obj.code);
        return card;
    }
}

;// ../../libs/common/src/vault/models/domain/field.ts





class Field extends Domain {
    constructor(obj) {
        var _a;
        super();
        this.type = FieldType.Text;
        if (obj == null) {
            return;
        }
        this.type = obj.type;
        this.linkedId = (_a = obj.linkedId) !== null && _a !== void 0 ? _a : undefined;
        this.name = conditionalEncString(obj.name);
        this.value = conditionalEncString(obj.value);
    }
    decrypt(encKey) {
        return this.decryptObj(this, new FieldView(this), ["name", "value"], encKey);
    }
    toFieldData() {
        const f = new FieldData();
        this.buildDataModel(this, f, {
            name: null,
            value: null,
            type: null,
            linkedId: null,
        }, ["type", "linkedId"]);
        return f;
    }
    static fromJSON(obj) {
        var _a, _b;
        if (obj == null) {
            return undefined;
        }
        const field = new Field();
        field.type = (_a = obj.type) !== null && _a !== void 0 ? _a : FieldType.Text;
        field.linkedId = (_b = obj.linkedId) !== null && _b !== void 0 ? _b : undefined;
        field.name = encStringFrom(obj.name);
        field.value = encStringFrom(obj.value);
        return field;
    }
    /**
     * Maps Field to SDK format.
     *
     * @returns {SdkField} The SDK field object.
     */
    toSdkField() {
        var _a, _b;
        return {
            name: (_a = this.name) === null || _a === void 0 ? void 0 : _a.toSdk(),
            value: (_b = this.value) === null || _b === void 0 ? void 0 : _b.toSdk(),
            type: normalizeFieldTypeForSdk(this.type),
            linkedId: normalizeLinkedIdTypeForSdk(this.linkedId),
        };
    }
    /**
     * Maps SDK Field to Field
     * @param obj The SDK Field object to map
     */
    static fromSdkField(obj) {
        if (obj == null) {
            return undefined;
        }
        const field = new Field();
        field.name = encStringFrom(obj.name);
        field.value = encStringFrom(obj.value);
        field.type = obj.type;
        field.linkedId = obj.linkedId;
        return field;
    }
}

;// ../../libs/common/src/vault/models/domain/identity.ts




class Identity extends Domain {
    constructor(obj) {
        super();
        if (obj == null) {
            return;
        }
        this.title = conditionalEncString(obj.title);
        this.firstName = conditionalEncString(obj.firstName);
        this.middleName = conditionalEncString(obj.middleName);
        this.lastName = conditionalEncString(obj.lastName);
        this.address1 = conditionalEncString(obj.address1);
        this.address2 = conditionalEncString(obj.address2);
        this.address3 = conditionalEncString(obj.address3);
        this.city = conditionalEncString(obj.city);
        this.state = conditionalEncString(obj.state);
        this.postalCode = conditionalEncString(obj.postalCode);
        this.country = conditionalEncString(obj.country);
        this.company = conditionalEncString(obj.company);
        this.email = conditionalEncString(obj.email);
        this.phone = conditionalEncString(obj.phone);
        this.ssn = conditionalEncString(obj.ssn);
        this.username = conditionalEncString(obj.username);
        this.passportNumber = conditionalEncString(obj.passportNumber);
        this.licenseNumber = conditionalEncString(obj.licenseNumber);
    }
    decrypt(encKey, context = "No Cipher Context") {
        return this.decryptObj(this, new IdentityView(), [
            "title",
            "firstName",
            "middleName",
            "lastName",
            "address1",
            "address2",
            "address3",
            "city",
            "state",
            "postalCode",
            "country",
            "company",
            "email",
            "phone",
            "ssn",
            "username",
            "passportNumber",
            "licenseNumber",
        ], encKey, "DomainType: Identity; " + context);
    }
    toIdentityData() {
        const i = new IdentityData();
        this.buildDataModel(this, i, {
            title: null,
            firstName: null,
            middleName: null,
            lastName: null,
            address1: null,
            address2: null,
            address3: null,
            city: null,
            state: null,
            postalCode: null,
            country: null,
            company: null,
            email: null,
            phone: null,
            ssn: null,
            username: null,
            passportNumber: null,
            licenseNumber: null,
        });
        return i;
    }
    static fromJSON(obj) {
        if (obj == null) {
            return undefined;
        }
        const identity = new Identity();
        identity.title = encStringFrom(obj.title);
        identity.firstName = encStringFrom(obj.firstName);
        identity.middleName = encStringFrom(obj.middleName);
        identity.lastName = encStringFrom(obj.lastName);
        identity.address1 = encStringFrom(obj.address1);
        identity.address2 = encStringFrom(obj.address2);
        identity.address3 = encStringFrom(obj.address3);
        identity.city = encStringFrom(obj.city);
        identity.state = encStringFrom(obj.state);
        identity.postalCode = encStringFrom(obj.postalCode);
        identity.country = encStringFrom(obj.country);
        identity.company = encStringFrom(obj.company);
        identity.email = encStringFrom(obj.email);
        identity.phone = encStringFrom(obj.phone);
        identity.ssn = encStringFrom(obj.ssn);
        identity.username = encStringFrom(obj.username);
        identity.passportNumber = encStringFrom(obj.passportNumber);
        identity.licenseNumber = encStringFrom(obj.licenseNumber);
        return identity;
    }
    /**
     * Maps Identity to SDK format.
     *
     * @returns {SdkIdentity} The SDK identity object.
     */
    toSdkIdentity() {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
        return {
            title: (_a = this.title) === null || _a === void 0 ? void 0 : _a.toSdk(),
            firstName: (_b = this.firstName) === null || _b === void 0 ? void 0 : _b.toSdk(),
            middleName: (_c = this.middleName) === null || _c === void 0 ? void 0 : _c.toSdk(),
            lastName: (_d = this.lastName) === null || _d === void 0 ? void 0 : _d.toSdk(),
            address1: (_e = this.address1) === null || _e === void 0 ? void 0 : _e.toSdk(),
            address2: (_f = this.address2) === null || _f === void 0 ? void 0 : _f.toSdk(),
            address3: (_g = this.address3) === null || _g === void 0 ? void 0 : _g.toSdk(),
            city: (_h = this.city) === null || _h === void 0 ? void 0 : _h.toSdk(),
            state: (_j = this.state) === null || _j === void 0 ? void 0 : _j.toSdk(),
            postalCode: (_k = this.postalCode) === null || _k === void 0 ? void 0 : _k.toSdk(),
            country: (_l = this.country) === null || _l === void 0 ? void 0 : _l.toSdk(),
            company: (_m = this.company) === null || _m === void 0 ? void 0 : _m.toSdk(),
            email: (_o = this.email) === null || _o === void 0 ? void 0 : _o.toSdk(),
            phone: (_p = this.phone) === null || _p === void 0 ? void 0 : _p.toSdk(),
            ssn: (_q = this.ssn) === null || _q === void 0 ? void 0 : _q.toSdk(),
            username: (_r = this.username) === null || _r === void 0 ? void 0 : _r.toSdk(),
            passportNumber: (_s = this.passportNumber) === null || _s === void 0 ? void 0 : _s.toSdk(),
            licenseNumber: (_t = this.licenseNumber) === null || _t === void 0 ? void 0 : _t.toSdk(),
        };
    }
    /**
     * Maps an SDK Identity object to an Identity
     * @param obj - The SDK Identity object
     */
    static fromSdkIdentity(obj) {
        if (obj == null) {
            return undefined;
        }
        const identity = new Identity();
        identity.title = encStringFrom(obj.title);
        identity.firstName = encStringFrom(obj.firstName);
        identity.middleName = encStringFrom(obj.middleName);
        identity.lastName = encStringFrom(obj.lastName);
        identity.address1 = encStringFrom(obj.address1);
        identity.address2 = encStringFrom(obj.address2);
        identity.address3 = encStringFrom(obj.address3);
        identity.city = encStringFrom(obj.city);
        identity.state = encStringFrom(obj.state);
        identity.postalCode = encStringFrom(obj.postalCode);
        identity.country = encStringFrom(obj.country);
        identity.company = encStringFrom(obj.company);
        identity.email = encStringFrom(obj.email);
        identity.phone = encStringFrom(obj.phone);
        identity.ssn = encStringFrom(obj.ssn);
        identity.username = encStringFrom(obj.username);
        identity.passportNumber = encStringFrom(obj.passportNumber);
        identity.licenseNumber = encStringFrom(obj.licenseNumber);
        return identity;
    }
}

;// ../../libs/common/src/vault/models/domain/fido2-credential.ts
var fido2_credential_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};





class Fido2Credential extends Domain {
    constructor(obj) {
        super();
        if (obj == null) {
            this.creationDate = new Date();
            return;
        }
        this.credentialId = new enc_string_EncString(obj.credentialId);
        this.keyType = new enc_string_EncString(obj.keyType);
        this.keyAlgorithm = new enc_string_EncString(obj.keyAlgorithm);
        this.keyCurve = new enc_string_EncString(obj.keyCurve);
        this.keyValue = new enc_string_EncString(obj.keyValue);
        this.rpId = new enc_string_EncString(obj.rpId);
        this.counter = new enc_string_EncString(obj.counter);
        this.discoverable = new enc_string_EncString(obj.discoverable);
        this.userHandle = conditionalEncString(obj.userHandle);
        this.userName = conditionalEncString(obj.userName);
        this.rpName = conditionalEncString(obj.rpName);
        this.userDisplayName = conditionalEncString(obj.userDisplayName);
        this.creationDate = new Date(obj.creationDate);
    }
    decrypt(decryptionKey) {
        return fido2_credential_awaiter(this, void 0, void 0, function* () {
            const view = yield this.decryptObj(this, new Fido2CredentialView(), [
                "credentialId",
                "keyType",
                "keyAlgorithm",
                "keyCurve",
                "keyValue",
                "rpId",
                "userHandle",
                "userName",
                "rpName",
                "userDisplayName",
            ], decryptionKey);
            const { counter } = yield this.decryptObj(this, { counter: "" }, ["counter"], decryptionKey);
            // Counter will end up as NaN if this fails
            view.counter = parseInt(counter);
            const { discoverable } = yield this.decryptObj(this, { discoverable: "" }, ["discoverable"], decryptionKey);
            view.discoverable = discoverable === "true";
            view.creationDate = this.creationDate;
            return view;
        });
    }
    toFido2CredentialData() {
        const i = new Fido2CredentialData();
        i.creationDate = this.creationDate.toISOString();
        this.buildDataModel(this, i, {
            credentialId: null,
            keyType: null,
            keyAlgorithm: null,
            keyCurve: null,
            keyValue: null,
            rpId: null,
            userHandle: null,
            userName: null,
            counter: null,
            rpName: null,
            userDisplayName: null,
            discoverable: null,
        });
        return i;
    }
    static fromJSON(obj) {
        if (obj == null) {
            return undefined;
        }
        const credential = new Fido2Credential();
        credential.credentialId = enc_string_EncString.fromJSON(obj.credentialId);
        credential.keyType = enc_string_EncString.fromJSON(obj.keyType);
        credential.keyAlgorithm = enc_string_EncString.fromJSON(obj.keyAlgorithm);
        credential.keyCurve = enc_string_EncString.fromJSON(obj.keyCurve);
        credential.keyValue = enc_string_EncString.fromJSON(obj.keyValue);
        credential.rpId = enc_string_EncString.fromJSON(obj.rpId);
        credential.userHandle = encStringFrom(obj.userHandle);
        credential.userName = encStringFrom(obj.userName);
        credential.counter = enc_string_EncString.fromJSON(obj.counter);
        credential.rpName = encStringFrom(obj.rpName);
        credential.userDisplayName = encStringFrom(obj.userDisplayName);
        credential.discoverable = enc_string_EncString.fromJSON(obj.discoverable);
        credential.creationDate = new Date(obj.creationDate);
        return credential;
    }
    /**
     *  Maps Fido2Credential to SDK format.
     *
     * @returns {SdkFido2Credential} The SDK Fido2Credential object.
     */
    toSdkFido2Credential() {
        var _a, _b, _c, _d, _e, _f;
        return {
            credentialId: (_a = this.credentialId) === null || _a === void 0 ? void 0 : _a.toSdk(),
            keyType: this.keyType.toSdk(),
            keyAlgorithm: this.keyAlgorithm.toSdk(),
            keyCurve: this.keyCurve.toSdk(),
            keyValue: this.keyValue.toSdk(),
            rpId: this.rpId.toSdk(),
            userHandle: (_b = this.userHandle) === null || _b === void 0 ? void 0 : _b.toSdk(),
            userName: (_c = this.userName) === null || _c === void 0 ? void 0 : _c.toSdk(),
            counter: this.counter.toSdk(),
            rpName: (_d = this.rpName) === null || _d === void 0 ? void 0 : _d.toSdk(),
            userDisplayName: (_e = this.userDisplayName) === null || _e === void 0 ? void 0 : _e.toSdk(),
            discoverable: (_f = this.discoverable) === null || _f === void 0 ? void 0 : _f.toSdk(),
            creationDate: this.creationDate.toISOString(),
        };
    }
    /**
     * Maps an SDK Fido2Credential object to a Fido2Credential
     * @param obj - The SDK Fido2Credential object
     */
    static fromSdkFido2Credential(obj) {
        if (obj == null) {
            return undefined;
        }
        const credential = new Fido2Credential();
        credential.credentialId = enc_string_EncString.fromJSON(obj.credentialId);
        credential.keyType = enc_string_EncString.fromJSON(obj.keyType);
        credential.keyAlgorithm = enc_string_EncString.fromJSON(obj.keyAlgorithm);
        credential.keyCurve = enc_string_EncString.fromJSON(obj.keyCurve);
        credential.keyValue = enc_string_EncString.fromJSON(obj.keyValue);
        credential.rpId = enc_string_EncString.fromJSON(obj.rpId);
        credential.counter = enc_string_EncString.fromJSON(obj.counter);
        credential.userHandle = encStringFrom(obj.userHandle);
        credential.userName = encStringFrom(obj.userName);
        credential.rpName = encStringFrom(obj.rpName);
        credential.userDisplayName = encStringFrom(obj.userDisplayName);
        credential.discoverable = enc_string_EncString.fromJSON(obj.discoverable);
        credential.creationDate = new Date(obj.creationDate);
        return credential;
    }
}

;// ../../libs/common/src/vault/models/domain/login-uri.ts
var login_uri_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};






class LoginUri extends Domain {
    constructor(obj) {
        var _a;
        super();
        if (obj == null) {
            return;
        }
        this.uri = conditionalEncString(obj.uri);
        this.uriChecksum = conditionalEncString(obj.uriChecksum);
        this.match = (_a = obj.match) !== null && _a !== void 0 ? _a : undefined;
    }
    decrypt(encKey, context = "No Cipher Context") {
        return this.decryptObj(this, new LoginUriView(this), ["uri"], encKey, context);
    }
    validateChecksum(clearTextUri, encKey) {
        return login_uri_awaiter(this, void 0, void 0, function* () {
            if (this.uriChecksum == null) {
                return false;
            }
            const encryptService = utils_Utils.getContainerService().getEncryptService();
            const localChecksum = yield encryptService.hash(clearTextUri, "sha256");
            const remoteChecksum = yield encryptService.decryptString(this.uriChecksum, encKey);
            return remoteChecksum === localChecksum;
        });
    }
    toLoginUriData() {
        const u = new LoginUriData();
        this.buildDataModel(this, u, {
            uri: null,
            uriChecksum: null,
            match: null,
        }, ["match"]);
        return u;
    }
    static fromJSON(obj) {
        var _a;
        if (obj == null) {
            return undefined;
        }
        const loginUri = new LoginUri();
        loginUri.uri = encStringFrom(obj.uri);
        loginUri.match = (_a = obj.match) !== null && _a !== void 0 ? _a : undefined;
        loginUri.uriChecksum = encStringFrom(obj.uriChecksum);
        return loginUri;
    }
    /**
     *  Maps LoginUri to SDK format.
     *
     * @returns {SdkLoginUri} The SDK login uri object.
     */
    toSdkLoginUri() {
        var _a, _b;
        return {
            uri: (_a = this.uri) === null || _a === void 0 ? void 0 : _a.toSdk(),
            uriChecksum: (_b = this.uriChecksum) === null || _b === void 0 ? void 0 : _b.toSdk(),
            match: normalizeUriMatchStrategyForSdk(this.match),
        };
    }
    static fromSdkLoginUri(obj) {
        if (obj == null) {
            return undefined;
        }
        const loginUri = new LoginUri();
        loginUri.uri = encStringFrom(obj.uri);
        loginUri.uriChecksum = encStringFrom(obj.uriChecksum);
        loginUri.match = obj.match;
        return loginUri;
    }
}

;// ../../libs/common/src/vault/models/domain/login.ts
var login_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};






class Login extends Domain {
    constructor(obj) {
        super();
        if (obj == null) {
            return;
        }
        this.passwordRevisionDate =
            obj.passwordRevisionDate != null ? new Date(obj.passwordRevisionDate) : undefined;
        this.autofillOnPageLoad = obj.autofillOnPageLoad;
        this.username = conditionalEncString(obj.username);
        this.password = conditionalEncString(obj.password);
        this.totp = conditionalEncString(obj.totp);
        if (obj.uris) {
            this.uris = obj.uris.map((u) => new LoginUri(u));
        }
        if (obj.fido2Credentials) {
            this.fido2Credentials = obj.fido2Credentials.map((key) => new Fido2Credential(key));
        }
    }
    decrypt(bypassValidation_1, encKey_1) {
        return login_awaiter(this, arguments, void 0, function* (bypassValidation, encKey, context = "No Cipher Context") {
            const view = yield this.decryptObj(this, new LoginView(this), ["username", "password", "totp"], encKey, `DomainType: Login; ${context}`);
            if (this.uris != null) {
                view.uris = [];
                for (let i = 0; i < this.uris.length; i++) {
                    // If the uri is null, there is nothing to decrypt or validate
                    if (this.uris[i].uri == null) {
                        continue;
                    }
                    const uri = yield this.uris[i].decrypt(encKey, context);
                    const uriString = uri.uri;
                    if (uriString == null) {
                        continue;
                    }
                    // URIs are shared remotely after decryption
                    // we need to validate that the string hasn't been changed by a compromised server
                    // This validation is tied to the existence of cypher.key for backwards compatibility
                    // So we bypass the validation if there's no cipher.key or proceed with the validation and
                    // Skip the value if it's been tampered with.
                    const isValidUri = bypassValidation || (yield this.uris[i].validateChecksum(uriString, encKey));
                    if (isValidUri) {
                        view.uris.push(uri);
                    }
                }
            }
            if (this.fido2Credentials != null) {
                view.fido2Credentials = yield Promise.all(this.fido2Credentials.map((key) => key.decrypt(encKey)));
            }
            return view;
        });
    }
    toLoginData() {
        const l = new LoginData();
        if (this.passwordRevisionDate != null) {
            l.passwordRevisionDate = this.passwordRevisionDate.toISOString();
        }
        if (this.autofillOnPageLoad != null) {
            l.autofillOnPageLoad = this.autofillOnPageLoad;
        }
        this.buildDataModel(this, l, {
            username: null,
            password: null,
            totp: null,
        });
        if (this.uris != null && this.uris.length > 0) {
            l.uris = this.uris.map((u) => u.toLoginUriData());
        }
        if (this.fido2Credentials != null && this.fido2Credentials.length > 0) {
            l.fido2Credentials = this.fido2Credentials.map((key) => key.toFido2CredentialData());
        }
        return l;
    }
    static fromJSON(obj) {
        var _a, _b, _c;
        if (obj == null) {
            return undefined;
        }
        const login = new Login();
        login.passwordRevisionDate =
            obj.passwordRevisionDate != null ? new Date(obj.passwordRevisionDate) : undefined;
        login.autofillOnPageLoad = obj.autofillOnPageLoad;
        login.username = encStringFrom(obj.username);
        login.password = encStringFrom(obj.password);
        login.totp = encStringFrom(obj.totp);
        login.uris = (_a = obj.uris) === null || _a === void 0 ? void 0 : _a.map((uri) => LoginUri.fromJSON(uri)).filter((u) => u != null);
        login.fido2Credentials =
            (_c = (_b = obj.fido2Credentials) === null || _b === void 0 ? void 0 : _b.map((key) => Fido2Credential.fromJSON(key)).filter((c) => c != null)) !== null && _c !== void 0 ? _c : undefined;
        return login;
    }
    /**
     * Maps Login to SDK format.
     *
     * @returns {SdkLogin} The SDK login object.
     */
    toSdkLogin() {
        var _a, _b, _c, _d, _e, _f, _g;
        return {
            uris: (_a = this.uris) === null || _a === void 0 ? void 0 : _a.map((u) => u.toSdkLoginUri()),
            username: (_b = this.username) === null || _b === void 0 ? void 0 : _b.toSdk(),
            password: (_c = this.password) === null || _c === void 0 ? void 0 : _c.toSdk(),
            passwordRevisionDate: (_d = this.passwordRevisionDate) === null || _d === void 0 ? void 0 : _d.toISOString(),
            totp: (_e = this.totp) === null || _e === void 0 ? void 0 : _e.toSdk(),
            autofillOnPageLoad: (_f = this.autofillOnPageLoad) !== null && _f !== void 0 ? _f : undefined,
            fido2Credentials: (_g = this.fido2Credentials) === null || _g === void 0 ? void 0 : _g.map((f) => f.toSdkFido2Credential()),
        };
    }
    /**
     * Maps an SDK Login object to a Login
     * @param obj - The SDK Login object
     */
    static fromSdkLogin(obj) {
        var _a, _b, _c, _d;
        if (!obj) {
            return undefined;
        }
        const login = new Login();
        login.passwordRevisionDate =
            obj.passwordRevisionDate != null ? new Date(obj.passwordRevisionDate) : undefined;
        login.autofillOnPageLoad = obj.autofillOnPageLoad;
        login.username = encStringFrom(obj.username);
        login.password = encStringFrom(obj.password);
        login.totp = encStringFrom(obj.totp);
        login.uris =
            (_b = (_a = obj.uris) === null || _a === void 0 ? void 0 : _a.filter((u) => u.uri != null).map((uri) => LoginUri.fromSdkLoginUri(uri)).filter((u) => u != null)) !== null && _b !== void 0 ? _b : undefined;
        login.fido2Credentials =
            (_d = (_c = obj.fido2Credentials) === null || _c === void 0 ? void 0 : _c.map((f) => Fido2Credential.fromSdkFido2Credential(f)).filter((c) => c != null)) !== null && _d !== void 0 ? _d : undefined;
        return login;
    }
}

;// ../../libs/common/src/vault/models/domain/password.ts




class Password extends Domain {
    constructor(obj) {
        super();
        if (obj == null) {
            return;
        }
        this.password = new enc_string_EncString(obj.password);
        this.lastUsedDate = new Date(obj.lastUsedDate);
    }
    decrypt(encKey) {
        return this.decryptObj(this, new PasswordHistoryView(this), ["password"], encKey, "DomainType: PasswordHistory");
    }
    toPasswordHistoryData() {
        const ph = new PasswordHistoryData();
        ph.lastUsedDate = this.lastUsedDate.toISOString();
        this.buildDataModel(this, ph, {
            password: null,
        });
        return ph;
    }
    static fromJSON(obj) {
        if (obj == null) {
            return undefined;
        }
        const passwordHistory = new Password();
        passwordHistory.password = enc_string_EncString.fromJSON(obj.password);
        passwordHistory.lastUsedDate = new Date(obj.lastUsedDate);
        return passwordHistory;
    }
    /**
     * Maps Password to SDK format.
     *
     * @returns {PasswordHistory} The SDK password history object.
     */
    toSdkPasswordHistory() {
        return {
            password: this.password.toSdk(),
            lastUsedDate: this.lastUsedDate.toISOString(),
        };
    }
    /**
     * Maps an SDK PasswordHistory object to a Password
     * @param obj - The SDK PasswordHistory object
     */
    static fromSdkPasswordHistory(obj) {
        if (!obj) {
            return undefined;
        }
        const passwordHistory = new Password();
        passwordHistory.password = enc_string_EncString.fromJSON(obj.password);
        passwordHistory.lastUsedDate = new Date(obj.lastUsedDate);
        return passwordHistory;
    }
}

;// ../../libs/common/src/vault/models/domain/secure-note.ts
var secure_note_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};




class SecureNote extends Domain {
    constructor(obj) {
        super();
        this.type = SecureNoteType.Generic;
        if (obj == null) {
            return;
        }
        this.type = obj.type;
    }
    decrypt() {
        return secure_note_awaiter(this, void 0, void 0, function* () {
            return new SecureNoteView(this);
        });
    }
    toSecureNoteData() {
        const n = new SecureNoteData();
        n.type = this.type;
        return n;
    }
    static fromJSON(obj) {
        if (obj == null) {
            return undefined;
        }
        const secureNote = new SecureNote();
        secureNote.type = obj.type;
        return secureNote;
    }
    /**
     * Maps Secure note to SDK format.
     *
     * @returns {SdkSecureNote} The SDK secure note object.
     */
    toSdkSecureNote() {
        return {
            type: normalizeSecureNoteTypeForSdk(this.type),
        };
    }
    /**
     * Maps an SDK SecureNote object to a SecureNote
     * @param obj - The SDK SecureNote object
     */
    static fromSdkSecureNote(obj) {
        if (obj == null) {
            return undefined;
        }
        const secureNote = new SecureNote();
        secureNote.type = obj.type;
        return secureNote;
    }
}

;// ../../libs/common/src/vault/models/domain/ssh-key.ts




class SshKey extends Domain {
    constructor(obj) {
        super();
        if (obj == null) {
            return;
        }
        this.privateKey = new enc_string_EncString(obj.privateKey);
        this.publicKey = new enc_string_EncString(obj.publicKey);
        this.keyFingerprint = new enc_string_EncString(obj.keyFingerprint);
    }
    decrypt(encKey, context = "No Cipher Context") {
        return this.decryptObj(this, new SshKeyView(), ["privateKey", "publicKey", "keyFingerprint"], encKey, "DomainType: SshKey; " + context);
    }
    toSshKeyData() {
        const c = new SshKeyData();
        this.buildDataModel(this, c, {
            privateKey: null,
            publicKey: null,
            keyFingerprint: null,
        });
        return c;
    }
    static fromJSON(obj) {
        if (obj == null) {
            return undefined;
        }
        const sshKey = new SshKey();
        sshKey.privateKey = enc_string_EncString.fromJSON(obj.privateKey);
        sshKey.publicKey = enc_string_EncString.fromJSON(obj.publicKey);
        sshKey.keyFingerprint = enc_string_EncString.fromJSON(obj.keyFingerprint);
        return sshKey;
    }
    /**
     * Maps SSH key to SDK format.
     *
     * @returns {SdkSshKey} The SDK SSH key object.
     */
    toSdkSshKey() {
        return {
            privateKey: this.privateKey.toSdk(),
            publicKey: this.publicKey.toSdk(),
            fingerprint: this.keyFingerprint.toSdk(),
        };
    }
    /**
     * Maps an SDK SshKey object to a SshKey
     * @param obj - The SDK SshKey object
     */
    static fromSdkSshKey(obj) {
        if (obj == null) {
            return undefined;
        }
        const sshKey = new SshKey();
        sshKey.privateKey = enc_string_EncString.fromJSON(obj.privateKey);
        sshKey.publicKey = enc_string_EncString.fromJSON(obj.publicKey);
        sshKey.keyFingerprint = enc_string_EncString.fromJSON(obj.fingerprint);
        return sshKey;
    }
}

;// ../../libs/common/src/vault/models/domain/cipher.ts
var cipher_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};





















class Cipher extends Domain {
    constructor(obj, localData) {
        var _a;
        super();
        this.initializerKey = InitializerKey.Cipher;
        this.id = "";
        this.name = new enc_string_EncString("");
        this.type = CipherType.Login;
        this.favorite = false;
        this.organizationUseTotp = false;
        this.edit = false;
        this.viewPassword = true;
        this.collectionIds = [];
        this.reprompt = CipherRepromptType.None;
        if (obj == null) {
            this.creationDate = this.revisionDate = new Date();
            return;
        }
        this.id = obj.id;
        this.organizationId = obj.organizationId;
        this.folderId = obj.folderId;
        this.name = new enc_string_EncString(obj.name);
        this.notes = conditionalEncString(obj.notes);
        this.type = obj.type;
        this.favorite = obj.favorite;
        this.organizationUseTotp = obj.organizationUseTotp;
        this.edit = obj.edit;
        this.viewPassword = obj.viewPassword;
        this.permissions = obj.permissions;
        this.revisionDate = new Date(obj.revisionDate);
        this.localData = localData;
        this.collectionIds = (_a = obj.collectionIds) !== null && _a !== void 0 ? _a : [];
        this.creationDate = new Date(obj.creationDate);
        this.deletedDate = obj.deletedDate != null ? new Date(obj.deletedDate) : undefined;
        this.archivedDate = obj.archivedDate != null ? new Date(obj.archivedDate) : undefined;
        this.reprompt = obj.reprompt;
        this.key = conditionalEncString(obj.key);
        switch (this.type) {
            case CipherType.Login:
                this.login = new Login(obj.login);
                break;
            case CipherType.SecureNote:
                this.secureNote = new SecureNote(obj.secureNote);
                break;
            case CipherType.Card:
                this.card = new Card(obj.card);
                break;
            case CipherType.Identity:
                this.identity = new Identity(obj.identity);
                break;
            case CipherType.SshKey:
                this.sshKey = new SshKey(obj.sshKey);
                break;
            default:
                break;
        }
        if (obj.attachments != null) {
            this.attachments = obj.attachments.map((a) => new Attachment(a));
        }
        if (obj.fields != null) {
            this.fields = obj.fields.map((f) => new Field(f));
        }
        if (obj.passwordHistory != null) {
            this.passwordHistory = obj.passwordHistory.map((ph) => new Password(ph));
        }
    }
    decrypt(userKeyOrOrgKey) {
        return cipher_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(userKeyOrOrgKey, "userKeyOrOrgKey", "Cipher decryption");
            const model = new CipherView(this);
            let bypassValidation = true;
            // By default, the user/organization key is used for decryption
            let cipherDecryptionKey = userKeyOrOrgKey;
            // If there is a cipher key present, unwrap it and use it for decryption
            if (this.key != null) {
                const encryptService = utils_Utils.getContainerService().getEncryptService();
                try {
                    const cipherKey = yield encryptService.unwrapSymmetricKey(this.key, userKeyOrOrgKey);
                    cipherDecryptionKey = cipherKey;
                    bypassValidation = false;
                }
                catch (_a) {
                    model.name = "[error: cannot decrypt]";
                    model.decryptionFailure = true;
                    return model;
                }
            }
            yield this.decryptObj(this, model, ["name", "notes"], cipherDecryptionKey);
            switch (this.type) {
                case CipherType.Login:
                    if (this.login != null) {
                        model.login = yield this.login.decrypt(bypassValidation, cipherDecryptionKey, `Cipher Id: ${this.id}`);
                    }
                    break;
                case CipherType.SecureNote:
                    if (this.secureNote != null) {
                        model.secureNote = yield this.secureNote.decrypt();
                    }
                    break;
                case CipherType.Card:
                    if (this.card != null) {
                        model.card = yield this.card.decrypt(cipherDecryptionKey, `Cipher Id: ${this.id}`);
                    }
                    break;
                case CipherType.Identity:
                    if (this.identity != null) {
                        model.identity = yield this.identity.decrypt(cipherDecryptionKey, `Cipher Id: ${this.id}`);
                    }
                    break;
                case CipherType.SshKey:
                    if (this.sshKey != null) {
                        model.sshKey = yield this.sshKey.decrypt(cipherDecryptionKey, `Cipher Id: ${this.id}`);
                    }
                    break;
                default:
                    break;
            }
            if (this.attachments != null && this.attachments.length > 0) {
                const attachments = [];
                for (const attachment of this.attachments) {
                    const decryptedAttachment = yield attachment.decrypt(cipherDecryptionKey, `Cipher Id: ${this.id}`);
                    attachments.push(decryptedAttachment);
                }
                model.attachments = attachments;
            }
            if (this.fields != null && this.fields.length > 0) {
                const fields = [];
                for (const field of this.fields) {
                    const decryptedField = yield field.decrypt(cipherDecryptionKey);
                    fields.push(decryptedField);
                }
                model.fields = fields;
            }
            if (this.passwordHistory != null && this.passwordHistory.length > 0) {
                const passwordHistory = [];
                for (const ph of this.passwordHistory) {
                    const decryptedPh = yield ph.decrypt(cipherDecryptionKey);
                    passwordHistory.push(decryptedPh);
                }
                model.passwordHistory = passwordHistory;
            }
            return model;
        });
    }
    toCipherData() {
        const c = new CipherData();
        c.id = this.id;
        if (this.organizationId != null) {
            c.organizationId = this.organizationId;
        }
        if (this.folderId != null) {
            c.folderId = this.folderId;
        }
        c.edit = this.edit;
        c.viewPassword = this.viewPassword;
        c.organizationUseTotp = this.organizationUseTotp;
        c.favorite = this.favorite;
        c.revisionDate = this.revisionDate.toISOString();
        c.type = this.type;
        c.collectionIds = this.collectionIds;
        c.creationDate = this.creationDate.toISOString();
        c.deletedDate = this.deletedDate != null ? this.deletedDate.toISOString() : undefined;
        c.reprompt = this.reprompt;
        if (this.key != null && this.key.encryptedString != null) {
            c.key = this.key.encryptedString;
        }
        if (this.permissions != null) {
            c.permissions = this.permissions;
        }
        c.archivedDate = this.archivedDate != null ? this.archivedDate.toISOString() : undefined;
        this.buildDataModel(this, c, {
            name: null,
            notes: null,
        });
        switch (c.type) {
            case CipherType.Login:
                if (this.login != null) {
                    c.login = this.login.toLoginData();
                }
                break;
            case CipherType.SecureNote:
                if (this.secureNote != null) {
                    c.secureNote = this.secureNote.toSecureNoteData();
                }
                break;
            case CipherType.Card:
                if (this.card != null) {
                    c.card = this.card.toCardData();
                }
                break;
            case CipherType.Identity:
                if (this.identity != null) {
                    c.identity = this.identity.toIdentityData();
                }
                break;
            case CipherType.SshKey:
                if (this.sshKey != null) {
                    c.sshKey = this.sshKey.toSshKeyData();
                }
                break;
            default:
                break;
        }
        if (this.fields != null) {
            c.fields = this.fields.map((f) => f.toFieldData());
        }
        if (this.attachments != null) {
            c.attachments = this.attachments.map((a) => a.toAttachmentData());
        }
        if (this.passwordHistory != null) {
            c.passwordHistory = this.passwordHistory.map((ph) => ph.toPasswordHistoryData());
        }
        return c;
    }
    static fromJSON(obj) {
        var _a, _b, _c;
        if (obj == null) {
            return undefined;
        }
        const domain = new Cipher();
        domain.id = obj.id;
        domain.organizationId = obj.organizationId;
        domain.folderId = obj.folderId;
        domain.type = obj.type;
        domain.favorite = obj.favorite;
        domain.organizationUseTotp = obj.organizationUseTotp;
        domain.edit = obj.edit;
        domain.viewPassword = obj.viewPassword;
        if (obj.permissions != null) {
            domain.permissions = new CipherPermissionsApi(obj.permissions);
        }
        domain.collectionIds = obj.collectionIds;
        domain.localData = obj.localData;
        domain.reprompt = obj.reprompt;
        domain.creationDate = new Date(obj.creationDate);
        domain.revisionDate = new Date(obj.revisionDate);
        domain.deletedDate = obj.deletedDate != null ? new Date(obj.deletedDate) : undefined;
        domain.archivedDate = obj.archivedDate != null ? new Date(obj.archivedDate) : undefined;
        domain.name = enc_string_EncString.fromJSON(obj.name);
        domain.notes = encStringFrom(obj.notes);
        domain.key = encStringFrom(obj.key);
        domain.attachments = (_a = obj.attachments) === null || _a === void 0 ? void 0 : _a.map((a) => Attachment.fromJSON(a)).filter((a) => a != null);
        domain.fields = (_b = obj.fields) === null || _b === void 0 ? void 0 : _b.map((f) => Field.fromJSON(f)).filter((f) => f != null);
        domain.passwordHistory = (_c = obj.passwordHistory) === null || _c === void 0 ? void 0 : _c.map((ph) => Password.fromJSON(ph)).filter((ph) => ph != null);
        switch (obj.type) {
            case CipherType.Card:
                if (obj.card != null) {
                    domain.card = Card.fromJSON(obj.card);
                }
                break;
            case CipherType.Identity:
                if (obj.identity != null) {
                    domain.identity = Identity.fromJSON(obj.identity);
                }
                break;
            case CipherType.Login:
                if (obj.login != null) {
                    domain.login = Login.fromJSON(obj.login);
                }
                break;
            case CipherType.SecureNote:
                if (obj.secureNote != null) {
                    domain.secureNote = SecureNote.fromJSON(obj.secureNote);
                }
                break;
            case CipherType.SshKey:
                if (obj.sshKey != null) {
                    domain.sshKey = SshKey.fromJSON(obj.sshKey);
                }
                break;
            default:
                break;
        }
        return domain;
    }
    /**
     * Maps Cipher to SDK format.
     *
     * @returns {SdkCipher} The SDK cipher object.
     */
    toSdkCipher() {
        var _a, _b, _c, _d, _e, _f, _g;
        const sdkCipher = {
            id: this.id ? asUuid(this.id) : undefined,
            organizationId: this.organizationId ? asUuid(this.organizationId) : undefined,
            folderId: this.folderId ? asUuid(this.folderId) : undefined,
            collectionIds: this.collectionIds ? this.collectionIds.map(asUuid) : [],
            key: (_a = this.key) === null || _a === void 0 ? void 0 : _a.toSdk(),
            name: this.name.toSdk(),
            notes: (_b = this.notes) === null || _b === void 0 ? void 0 : _b.toSdk(),
            type: this.type,
            favorite: this.favorite,
            organizationUseTotp: this.organizationUseTotp,
            edit: this.edit,
            permissions: this.permissions
                ? {
                    delete: this.permissions.delete,
                    restore: this.permissions.restore,
                }
                : undefined,
            viewPassword: this.viewPassword,
            localData: toSdkLocalData(this.localData),
            attachments: (_c = this.attachments) === null || _c === void 0 ? void 0 : _c.map((a) => a.toSdkAttachment()),
            fields: (_d = this.fields) === null || _d === void 0 ? void 0 : _d.map((f) => f.toSdkField()),
            passwordHistory: (_e = this.passwordHistory) === null || _e === void 0 ? void 0 : _e.map((ph) => ph.toSdkPasswordHistory()),
            revisionDate: this.revisionDate.toISOString(),
            creationDate: this.creationDate.toISOString(),
            deletedDate: (_f = this.deletedDate) === null || _f === void 0 ? void 0 : _f.toISOString(),
            archivedDate: (_g = this.archivedDate) === null || _g === void 0 ? void 0 : _g.toISOString(),
            reprompt: normalizeCipherRepromptTypeForSdk(this.reprompt),
            // Initialize all cipher-type-specific properties as undefined
            login: undefined,
            identity: undefined,
            card: undefined,
            secureNote: undefined,
            sshKey: undefined,
            data: undefined,
        };
        switch (this.type) {
            case CipherType.Login:
                if (this.login != null) {
                    sdkCipher.login = this.login.toSdkLogin();
                }
                break;
            case CipherType.SecureNote:
                if (this.secureNote != null) {
                    sdkCipher.secureNote = this.secureNote.toSdkSecureNote();
                }
                break;
            case CipherType.Card:
                if (this.card != null) {
                    sdkCipher.card = this.card.toSdkCard();
                }
                break;
            case CipherType.Identity:
                if (this.identity != null) {
                    sdkCipher.identity = this.identity.toSdkIdentity();
                }
                break;
            case CipherType.SshKey:
                if (this.sshKey != null) {
                    sdkCipher.sshKey = this.sshKey.toSdkSshKey();
                }
                break;
            default:
                break;
        }
        return sdkCipher;
    }
    /**
     * Maps an SDK Cipher object to a Cipher
     * @param sdkCipher - The SDK Cipher object
     */
    static fromSdkCipher(sdkCipher) {
        var _a, _b, _c;
        if (sdkCipher == null) {
            return undefined;
        }
        const cipher = new Cipher();
        cipher.id = sdkCipher.id ? uuidAsString(sdkCipher.id) : "";
        cipher.organizationId = sdkCipher.organizationId
            ? uuidAsString(sdkCipher.organizationId)
            : undefined;
        cipher.folderId = sdkCipher.folderId ? uuidAsString(sdkCipher.folderId) : undefined;
        cipher.collectionIds = sdkCipher.collectionIds ? sdkCipher.collectionIds.map(uuidAsString) : [];
        cipher.key = encStringFrom(sdkCipher.key);
        cipher.name = enc_string_EncString.fromJSON(sdkCipher.name);
        cipher.notes = encStringFrom(sdkCipher.notes);
        cipher.type = sdkCipher.type;
        cipher.favorite = sdkCipher.favorite;
        cipher.organizationUseTotp = sdkCipher.organizationUseTotp;
        cipher.edit = sdkCipher.edit;
        cipher.permissions = CipherPermissionsApi.fromSdkCipherPermissions(sdkCipher.permissions);
        cipher.viewPassword = sdkCipher.viewPassword;
        cipher.localData = fromSdkLocalData(sdkCipher.localData);
        cipher.attachments = (_a = sdkCipher.attachments) === null || _a === void 0 ? void 0 : _a.map((a) => Attachment.fromSdkAttachment(a)).filter((a) => a != null);
        cipher.fields = (_b = sdkCipher.fields) === null || _b === void 0 ? void 0 : _b.map((f) => Field.fromSdkField(f)).filter((f) => f != null);
        cipher.passwordHistory = (_c = sdkCipher.passwordHistory) === null || _c === void 0 ? void 0 : _c.map((ph) => Password.fromSdkPasswordHistory(ph)).filter((ph) => ph != null);
        cipher.creationDate = new Date(sdkCipher.creationDate);
        cipher.revisionDate = new Date(sdkCipher.revisionDate);
        cipher.deletedDate = sdkCipher.deletedDate ? new Date(sdkCipher.deletedDate) : undefined;
        cipher.archivedDate = sdkCipher.archivedDate ? new Date(sdkCipher.archivedDate) : undefined;
        cipher.reprompt = sdkCipher.reprompt;
        // Cipher type specific properties
        cipher.login = Login.fromSdkLogin(sdkCipher.login);
        cipher.secureNote = SecureNote.fromSdkSecureNote(sdkCipher.secureNote);
        cipher.card = Card.fromSdkCard(sdkCipher.card);
        cipher.identity = Identity.fromSdkIdentity(sdkCipher.identity);
        cipher.sshKey = SshKey.fromSdkSshKey(sdkCipher.sshKey);
        return cipher;
    }
}

;// ../../libs/common/src/models/export/utils.ts
function safeGetString(value) {
    if (value == null) {
        return undefined;
    }
    if (typeof value == "string") {
        return value;
    }
    return value === null || value === void 0 ? void 0 : value.encryptedString;
}

;// ../../libs/common/src/models/export/card.export.ts




class CardExport {
    static template() {
        const req = new CardExport();
        req.cardholderName = "John Doe";
        req.brand = "visa";
        req.number = "4242424242424242";
        req.expMonth = "04";
        req.expYear = "2023";
        req.code = "123";
        return req;
    }
    static toView(req, view = new CardView()) {
        view.cardholderName = req.cardholderName;
        view.brand = req.brand;
        view.number = req.number;
        view.expMonth = req.expMonth;
        view.expYear = req.expYear;
        view.code = req.code;
        return view;
    }
    static toDomain(req, domain = new Card()) {
        domain.cardholderName =
            req.cardholderName != null ? new enc_string_EncString(req.cardholderName) : undefined;
        domain.brand = req.brand != null ? new enc_string_EncString(req.brand) : undefined;
        domain.number = req.number != null ? new enc_string_EncString(req.number) : undefined;
        domain.expMonth = req.expMonth != null ? new enc_string_EncString(req.expMonth) : undefined;
        domain.expYear = req.expYear != null ? new enc_string_EncString(req.expYear) : undefined;
        domain.code = req.code != null ? new enc_string_EncString(req.code) : undefined;
        return domain;
    }
    constructor(o) {
        if (o == null) {
            return;
        }
        this.cardholderName = safeGetString(o.cardholderName);
        this.brand = safeGetString(o.brand);
        this.number = safeGetString(o.number);
        this.expMonth = safeGetString(o.expMonth);
        this.expYear = safeGetString(o.expYear);
        this.code = safeGetString(o.code);
    }
}

;// ../../libs/common/src/models/export/field.export.ts





class FieldExport {
    static template() {
        const req = new FieldExport();
        req.name = "Field name";
        req.value = "Some value";
        req.type = FieldType.Text;
        return req;
    }
    static toView(req, view = new FieldView()) {
        view.type = req.type;
        view.value = req.value;
        view.name = req.name;
        view.linkedId = req.linkedId;
        return view;
    }
    static toDomain(req, domain = new Field()) {
        domain.type = req.type;
        domain.value = req.value != null ? new enc_string_EncString(req.value) : undefined;
        domain.name = req.name != null ? new enc_string_EncString(req.name) : undefined;
        domain.linkedId = req.linkedId;
        return domain;
    }
    constructor(o) {
        this.type = FieldType.Text;
        if (o == null) {
            return;
        }
        this.name = safeGetString(o.name);
        this.value = safeGetString(o.value);
        this.type = o.type;
        this.linkedId = o.linkedId;
    }
}

;// ../../libs/common/src/models/export/identity.export.ts




class IdentityExport {
    static template() {
        const req = new IdentityExport();
        req.title = "Mr";
        req.firstName = "John";
        req.middleName = "William";
        req.lastName = "Doe";
        req.address1 = "123 Any St";
        req.address2 = "Apt #123";
        req.city = "New York";
        req.state = "NY";
        req.postalCode = "10001";
        req.country = "US";
        req.company = "Acme Inc.";
        req.email = "john@company.com";
        req.phone = "5555551234";
        req.ssn = "000-123-4567";
        req.username = "jdoe";
        req.passportNumber = "US-123456789";
        req.licenseNumber = "D123-12-123-12333";
        return req;
    }
    static toView(req, view = new IdentityView()) {
        view.title = req.title;
        view.firstName = req.firstName;
        view.middleName = req.middleName;
        view.lastName = req.lastName;
        view.address1 = req.address1;
        view.address2 = req.address2;
        view.address3 = req.address3;
        view.city = req.city;
        view.state = req.state;
        view.postalCode = req.postalCode;
        view.country = req.country;
        view.company = req.company;
        view.email = req.email;
        view.phone = req.phone;
        view.ssn = req.ssn;
        view.username = req.username;
        view.passportNumber = req.passportNumber;
        view.licenseNumber = req.licenseNumber;
        return view;
    }
    static toDomain(req, domain = new Identity()) {
        domain.title = req.title != null ? new enc_string_EncString(req.title) : undefined;
        domain.firstName = req.firstName != null ? new enc_string_EncString(req.firstName) : undefined;
        domain.middleName = req.middleName != null ? new enc_string_EncString(req.middleName) : undefined;
        domain.lastName = req.lastName != null ? new enc_string_EncString(req.lastName) : undefined;
        domain.address1 = req.address1 != null ? new enc_string_EncString(req.address1) : undefined;
        domain.address2 = req.address2 != null ? new enc_string_EncString(req.address2) : undefined;
        domain.address3 = req.address3 != null ? new enc_string_EncString(req.address3) : undefined;
        domain.city = req.city != null ? new enc_string_EncString(req.city) : undefined;
        domain.state = req.state != null ? new enc_string_EncString(req.state) : undefined;
        domain.postalCode = req.postalCode != null ? new enc_string_EncString(req.postalCode) : undefined;
        domain.country = req.country != null ? new enc_string_EncString(req.country) : undefined;
        domain.company = req.company != null ? new enc_string_EncString(req.company) : undefined;
        domain.email = req.email != null ? new enc_string_EncString(req.email) : undefined;
        domain.phone = req.phone != null ? new enc_string_EncString(req.phone) : undefined;
        domain.ssn = req.ssn != null ? new enc_string_EncString(req.ssn) : undefined;
        domain.username = req.username != null ? new enc_string_EncString(req.username) : undefined;
        domain.passportNumber =
            req.passportNumber != null ? new enc_string_EncString(req.passportNumber) : undefined;
        domain.licenseNumber = req.licenseNumber != null ? new enc_string_EncString(req.licenseNumber) : undefined;
        return domain;
    }
    constructor(o) {
        if (o == null) {
            return;
        }
        this.title = safeGetString(o.title);
        this.firstName = safeGetString(o.firstName);
        this.middleName = safeGetString(o.middleName);
        this.lastName = safeGetString(o.lastName);
        this.address1 = safeGetString(o.address1);
        this.address2 = safeGetString(o.address2);
        this.address3 = safeGetString(o.address3);
        this.city = safeGetString(o.city);
        this.state = safeGetString(o.state);
        this.postalCode = safeGetString(o.postalCode);
        this.country = safeGetString(o.country);
        this.company = safeGetString(o.company);
        this.email = safeGetString(o.email);
        this.phone = safeGetString(o.phone);
        this.ssn = safeGetString(o.ssn);
        this.username = safeGetString(o.username);
        this.passportNumber = safeGetString(o.passportNumber);
        this.licenseNumber = safeGetString(o.licenseNumber);
    }
}

;// ../../libs/common/src/models/export/fido2-credential.export.ts




/**
 * Represents format of Fido2 Credentials in JSON exports.
 */
class Fido2CredentialExport {
    /**
     * Generates a template for Fido2CredentialExport
     * @returns Instance of Fido2CredentialExport with predefined values.
     */
    static template() {
        const req = new Fido2CredentialExport();
        req.credentialId = "keyId";
        req.keyType = "keyType";
        req.keyAlgorithm = "keyAlgorithm";
        req.keyCurve = "keyCurve";
        req.keyValue = "keyValue";
        req.rpId = "rpId";
        req.userHandle = "userHandle";
        req.userName = "userName";
        req.counter = "counter";
        req.rpName = "rpName";
        req.userDisplayName = "userDisplayName";
        req.discoverable = "false";
        req.creationDate = new Date();
        return req;
    }
    /**
     * Converts a Fido2CredentialExport object to its view representation.
     * @param req - The Fido2CredentialExport object to be converted.
     * @param view - (Optional) The Fido2CredentialView object to popualte with Fido2CredentialExport data
     * @returns Fido2CredentialView - The populated view, or a new instance if none was provided.
     */
    static toView(req, view = new Fido2CredentialView()) {
        view.credentialId = req.credentialId;
        view.keyType = req.keyType;
        view.keyAlgorithm = req.keyAlgorithm;
        view.keyCurve = req.keyCurve;
        view.keyValue = req.keyValue;
        view.rpId = req.rpId;
        view.userHandle = req.userHandle;
        view.userName = req.userName;
        view.counter = parseInt(req.counter);
        view.rpName = req.rpName;
        view.userDisplayName = req.userDisplayName;
        view.discoverable = req.discoverable === "true";
        view.creationDate = new Date(req.creationDate);
        return view;
    }
    /**
     * Converts a Fido2CredentialExport object to its domain representation.
     * @param req - The Fido2CredentialExport object to be converted.
     * @param domain - (Optional) The Fido2Credential object to popualte with Fido2CredentialExport data
     * @returns Fido2Credential - The populated domain, or a new instance if none was provided.
     */
    static toDomain(req, domain = new Fido2Credential()) {
        domain.credentialId = new enc_string_EncString(req.credentialId);
        domain.keyType = new enc_string_EncString(req.keyType);
        domain.keyAlgorithm = new enc_string_EncString(req.keyAlgorithm);
        domain.keyCurve = new enc_string_EncString(req.keyCurve);
        domain.keyValue = new enc_string_EncString(req.keyValue);
        domain.rpId = new enc_string_EncString(req.rpId);
        domain.userHandle = req.userHandle != null ? new enc_string_EncString(req.userHandle) : undefined;
        domain.userName = req.userName != null ? new enc_string_EncString(req.userName) : undefined;
        domain.counter = new enc_string_EncString(req.counter);
        domain.rpName = req.rpName != null ? new enc_string_EncString(req.rpName) : undefined;
        domain.userDisplayName =
            req.userDisplayName != null ? new enc_string_EncString(req.userDisplayName) : undefined;
        domain.discoverable = new enc_string_EncString(req.discoverable);
        domain.creationDate = new Date(req.creationDate);
        return domain;
    }
    /**
     * Constructs a new Fid2CredentialExport instance.
     *
     * @param o - The credential storing the data being exported. When not provided, an empty export is created instead.
     */
    constructor(o) {
        var _a, _b, _c, _d, _e, _f, _g, _h;
        this.credentialId = "";
        this.keyType = "";
        this.keyAlgorithm = "";
        this.keyCurve = "";
        this.keyValue = "";
        this.rpId = "";
        this.counter = "";
        this.discoverable = "false";
        this.creationDate = new Date();
        if (o == null) {
            return;
        }
        this.credentialId = (_a = safeGetString(o.credentialId)) !== null && _a !== void 0 ? _a : "";
        this.keyType = (_b = safeGetString(o.keyType)) !== null && _b !== void 0 ? _b : "";
        this.keyAlgorithm = (_c = safeGetString(o.keyAlgorithm)) !== null && _c !== void 0 ? _c : "";
        this.keyCurve = (_d = safeGetString(o.keyCurve)) !== null && _d !== void 0 ? _d : "";
        this.keyValue = (_e = safeGetString(o.keyValue)) !== null && _e !== void 0 ? _e : "";
        this.rpId = (_f = safeGetString(o.rpId)) !== null && _f !== void 0 ? _f : "";
        this.userHandle = safeGetString(o.userHandle);
        this.userName = safeGetString(o.userName);
        this.counter =
            (_g = safeGetString(o instanceof Fido2CredentialView ? String(o.counter) : o.counter)) !== null && _g !== void 0 ? _g : "";
        this.rpName = safeGetString(o.rpName);
        this.userDisplayName = safeGetString(o.userDisplayName);
        this.discoverable =
            (_h = safeGetString(o instanceof Fido2CredentialView ? String(o.discoverable) : o.discoverable)) !== null && _h !== void 0 ? _h : "false";
        this.creationDate = o.creationDate;
    }
}

;// ../../libs/common/src/models/export/login-uri.export.ts




class LoginUriExport {
    static template() {
        const req = new LoginUriExport();
        req.uri = "https://google.com";
        return req;
    }
    static toView(req, view = new LoginUriView()) {
        view.uri = req.uri;
        view.match = req.match;
        return view;
    }
    static toDomain(req, domain = new LoginUri()) {
        domain.uri = req.uri != null ? new enc_string_EncString(req.uri) : undefined;
        domain.uriChecksum = req.uriChecksum != null ? new enc_string_EncString(req.uriChecksum) : undefined;
        domain.match = req.match;
        return domain;
    }
    constructor(o) {
        var _a;
        if (o == null) {
            return;
        }
        this.uri = safeGetString(o.uri);
        if ("uriChecksum" in o) {
            this.uriChecksum = (_a = o.uriChecksum) === null || _a === void 0 ? void 0 : _a.encryptedString;
        }
        this.match = o.match;
    }
}

;// ../../libs/common/src/models/export/login.export.ts






class LoginExport {
    static template() {
        const req = new LoginExport();
        req.uris = [];
        req.username = "jdoe";
        req.password = "myp@ssword123";
        req.totp = "JBSWY3DPEHPK3PXP";
        req.fido2Credentials = [];
        return req;
    }
    static toView(req, view = new LoginView()) {
        if (req.uris != null) {
            view.uris = req.uris.map((u) => LoginUriExport.toView(u));
        }
        view.username = req.username;
        view.password = req.password;
        view.totp = req.totp;
        if (req.fido2Credentials != null) {
            view.fido2Credentials = req.fido2Credentials.map((key) => Fido2CredentialExport.toView(key));
        }
        return view;
    }
    static toDomain(req, domain = new Login()) {
        if (req.uris != null) {
            domain.uris = req.uris.map((u) => LoginUriExport.toDomain(u));
        }
        domain.username = req.username != null ? new enc_string_EncString(req.username) : undefined;
        domain.password = req.password != null ? new enc_string_EncString(req.password) : undefined;
        domain.totp = req.totp != null ? new enc_string_EncString(req.totp) : undefined;
        if (req.fido2Credentials != null) {
            domain.fido2Credentials = req.fido2Credentials.map((f2) => Fido2CredentialExport.toDomain(f2));
        }
        return domain;
    }
    constructor(o) {
        if (o == null) {
            return;
        }
        if (o.uris != null) {
            this.uris = o.uris.map((u) => new LoginUriExport(u));
        }
        if (o.fido2Credentials != null) {
            this.fido2Credentials = o.fido2Credentials.map((key) => new Fido2CredentialExport(key));
        }
        this.username = safeGetString(o.username);
        this.password = safeGetString(o.password);
        this.totp = safeGetString(o.totp);
    }
}

;// ../../libs/common/src/models/export/password-history.export.ts




class PasswordHistoryExport {
    static template() {
        const req = new PasswordHistoryExport();
        return req;
    }
    static toView(req, view = new PasswordHistoryView()) {
        view.password = req.password;
        view.lastUsedDate = req.lastUsedDate ? new Date(req.lastUsedDate) : new Date();
        return view;
    }
    static toDomain(req, domain = new Password()) {
        domain.password = new enc_string_EncString(req.password);
        domain.lastUsedDate = req.lastUsedDate ? new Date(req.lastUsedDate) : new Date();
        return domain;
    }
    constructor(o) {
        var _a, _b;
        this.password = "";
        if (o == null) {
            return;
        }
        this.password = (_a = safeGetString(o.password)) !== null && _a !== void 0 ? _a : "";
        this.lastUsedDate = (_b = o.lastUsedDate) !== null && _b !== void 0 ? _b : undefined;
    }
}

;// ../../libs/common/src/models/export/secure-note.export.ts



class SecureNoteExport {
    static template() {
        const req = new SecureNoteExport();
        req.type = SecureNoteType.Generic;
        return req;
    }
    static toView(req, view = new SecureNoteView()) {
        view.type = req.type;
        return view;
    }
    static toDomain(req, view = new SecureNote()) {
        view.type = req.type;
        return view;
    }
    constructor(o) {
        this.type = SecureNoteType.Generic;
        if (o == null) {
            return;
        }
        this.type = o.type;
    }
}

;// ../../libs/common/src/models/export/ssh-key.export.ts




class SshKeyExport {
    static template() {
        const req = new SshKeyExport();
        req.privateKey = "";
        req.publicKey = "";
        req.keyFingerprint = "";
        return req;
    }
    static toView(req, view = new SshKeyView()) {
        if (req == null) {
            return undefined;
        }
        // Validate required fields
        if (!req.privateKey || req.privateKey.trim() === "") {
            throw new Error("SSH key private key is required.");
        }
        if (!req.publicKey || req.publicKey.trim() === "") {
            throw new Error("SSH key public key is required.");
        }
        if (!req.keyFingerprint || req.keyFingerprint.trim() === "") {
            throw new Error("SSH key fingerprint is required.");
        }
        view.privateKey = req.privateKey;
        view.publicKey = req.publicKey;
        view.keyFingerprint = req.keyFingerprint;
        return view;
    }
    static toDomain(req, domain = new SshKey()) {
        domain.privateKey = new enc_string_EncString(req.privateKey);
        domain.publicKey = new enc_string_EncString(req.publicKey);
        domain.keyFingerprint = new enc_string_EncString(req.keyFingerprint);
        return domain;
    }
    constructor(o) {
        var _a, _b, _c;
        this.privateKey = "";
        this.publicKey = "";
        this.keyFingerprint = "";
        if (o == null) {
            return;
        }
        this.privateKey = (_a = safeGetString(o.privateKey)) !== null && _a !== void 0 ? _a : "";
        this.publicKey = (_b = safeGetString(o.publicKey)) !== null && _b !== void 0 ? _b : "";
        this.keyFingerprint = (_c = safeGetString(o.keyFingerprint)) !== null && _c !== void 0 ? _c : "";
    }
}

;// ../../libs/common/src/models/export/cipher.export.ts













class CipherExport {
    constructor() {
        this.type = CipherType.Login;
        this.name = "";
        this.favorite = false;
        this.reprompt = CipherRepromptType.None;
    }
    static template() {
        const req = new CipherExport();
        req.type = CipherType.Login;
        req.name = "Item name";
        req.notes = "Some notes about this item.";
        req.favorite = false;
        req.fields = [];
        req.reprompt = CipherRepromptType.None;
        req.passwordHistory = [];
        return req;
    }
    static toView(req, view = new CipherView()) {
        var _a, _b, _c;
        view.type = req.type;
        view.folderId = req.folderId;
        if (view.organizationId == null) {
            view.organizationId = req.organizationId;
        }
        if (view.collectionIds || req.collectionIds) {
            const set = new Set(((_a = view.collectionIds) !== null && _a !== void 0 ? _a : []).concat((_b = req.collectionIds) !== null && _b !== void 0 ? _b : []));
            view.collectionIds = Array.from(set.values());
        }
        view.name = req.name;
        view.notes = req.notes;
        view.favorite = req.favorite;
        view.reprompt = (_c = req.reprompt) !== null && _c !== void 0 ? _c : CipherRepromptType.None;
        view.key = req.key != null ? new enc_string_EncString(req.key) : undefined;
        if (req.fields != null) {
            view.fields = req.fields.map((f) => FieldExport.toView(f));
        }
        switch (req.type) {
            case CipherType.Login:
                if (req.login != null) {
                    view.login = LoginExport.toView(req.login);
                }
                break;
            case CipherType.SecureNote:
                if (req.secureNote != null) {
                    view.secureNote = SecureNoteExport.toView(req.secureNote);
                }
                break;
            case CipherType.Card:
                if (req.card != null) {
                    view.card = CardExport.toView(req.card);
                }
                break;
            case CipherType.Identity:
                if (req.identity != null) {
                    view.identity = IdentityExport.toView(req.identity);
                }
                break;
            case CipherType.SshKey:
                if (req.sshKey != null) {
                    // toView only returns undefined when req is null, which we've already checked
                    view.sshKey = SshKeyExport.toView(req.sshKey);
                }
                break;
        }
        if (req.passwordHistory != null) {
            view.passwordHistory = req.passwordHistory.map((ph) => PasswordHistoryExport.toView(ph));
        }
        view.creationDate = req.creationDate ? new Date(req.creationDate) : view.creationDate;
        view.revisionDate = req.revisionDate ? new Date(req.revisionDate) : view.revisionDate;
        view.deletedDate = req.deletedDate ? new Date(req.deletedDate) : view.deletedDate;
        view.archivedDate = req.archivedDate ? new Date(req.archivedDate) : view.archivedDate;
        return view;
    }
    static toDomain(req, domain = new Cipher()) {
        var _a;
        domain.type = req.type;
        domain.folderId = req.folderId;
        if (domain.organizationId == null) {
            domain.organizationId = req.organizationId;
        }
        domain.name = req.name != null ? new enc_string_EncString(req.name) : new enc_string_EncString("");
        domain.notes = req.notes != null ? new enc_string_EncString(req.notes) : undefined;
        domain.favorite = req.favorite;
        domain.reprompt = (_a = req.reprompt) !== null && _a !== void 0 ? _a : CipherRepromptType.None;
        domain.key = req.key != null ? new enc_string_EncString(req.key) : undefined;
        if (req.fields != null) {
            domain.fields = req.fields.map((f) => FieldExport.toDomain(f));
        }
        switch (req.type) {
            case CipherType.Login:
                if (req.login != null) {
                    domain.login = LoginExport.toDomain(req.login);
                }
                break;
            case CipherType.SecureNote:
                if (req.secureNote != null) {
                    domain.secureNote = SecureNoteExport.toDomain(req.secureNote);
                }
                break;
            case CipherType.Card:
                if (req.card != null) {
                    domain.card = CardExport.toDomain(req.card);
                }
                break;
            case CipherType.Identity:
                if (req.identity != null) {
                    domain.identity = IdentityExport.toDomain(req.identity);
                }
                break;
            case CipherType.SshKey:
                if (req.sshKey != null) {
                    domain.sshKey = SshKeyExport.toDomain(req.sshKey);
                }
                break;
        }
        if (req.passwordHistory != null) {
            domain.passwordHistory = req.passwordHistory.map((ph) => PasswordHistoryExport.toDomain(ph));
        }
        domain.creationDate = req.creationDate ? new Date(req.creationDate) : domain.creationDate;
        domain.revisionDate = req.revisionDate ? new Date(req.revisionDate) : domain.revisionDate;
        domain.deletedDate = req.deletedDate ? new Date(req.deletedDate) : undefined;
        domain.archivedDate = req.archivedDate ? new Date(req.archivedDate) : undefined;
        return domain;
    }
    // Use build method instead of ctor so that we can control order of JSON stringify for pretty print
    build(o) {
        var _a, _b;
        this.organizationId = o.organizationId;
        this.folderId = o.folderId;
        this.type = o.type;
        this.reprompt = o.reprompt;
        this.name = (_a = safeGetString(o.name)) !== null && _a !== void 0 ? _a : "";
        this.notes = safeGetString(o.notes);
        if ("key" in o) {
            this.key = (_b = o.key) === null || _b === void 0 ? void 0 : _b.encryptedString;
        }
        this.favorite = o.favorite;
        if (o.fields != null) {
            this.fields = o.fields.map((f) => new FieldExport(f));
        }
        switch (o.type) {
            case CipherType.Login:
                this.login = new LoginExport(o.login);
                break;
            case CipherType.SecureNote:
                this.secureNote = new SecureNoteExport(o.secureNote);
                break;
            case CipherType.Card:
                this.card = new CardExport(o.card);
                break;
            case CipherType.Identity:
                this.identity = new IdentityExport(o.identity);
                break;
            case CipherType.SshKey:
                this.sshKey = new SshKeyExport(o.sshKey);
                break;
        }
        if (o.passwordHistory != null) {
            this.passwordHistory = o.passwordHistory.map((ph) => new PasswordHistoryExport(ph));
        }
        this.creationDate = o.creationDate;
        this.revisionDate = o.revisionDate;
        this.deletedDate = o.deletedDate;
        this.archivedDate = o.archivedDate;
    }
}

;// ../../libs/common/src/models/export/cipher-with-ids.export.ts

class CipherWithIdExport extends CipherExport {
    constructor() {
        super(...arguments);
        this.id = "";
        this.collectionIds = [];
    }
    // Use build method instead of ctor so that we can control order of JSON stringify for pretty print
    build(o) {
        this.id = o.id;
        super.build(o);
        this.collectionIds = o.collectionIds;
    }
}

;// ./src/models/response/login.response.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

class LoginResponse extends LoginExport {
    constructor(o, viewPassword) {
        super(o);
        this.passwordRevisionDate = o.passwordRevisionDate != null ? o.passwordRevisionDate : null;
        if (viewPassword === false) {
            this.password = null;
            this.totp = null;
        }
    }
}

;// ./src/vault/models/attachment.response.ts
class AttachmentResponse {
    constructor(o) {
        this.id = o.id;
        this.fileName = o.fileName;
        this.size = o.size;
        this.sizeName = o.sizeName;
        this.url = o.url;
    }
}

;// ./src/vault/models/password-history.response.ts
class PasswordHistoryResponse {
    constructor(o) {
        this.lastUsedDate = o.lastUsedDate;
        this.password = o.password;
    }
}

;// ./src/vault/models/cipher.response.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore





class CipherResponse extends CipherWithIdExport {
    constructor(o) {
        super();
        this.object = "item";
        this.build(o);
        if (o.attachments != null) {
            this.attachments = o.attachments.map((a) => new AttachmentResponse(a));
        }
        this.revisionDate = o.revisionDate;
        if (o.creationDate != null) {
            this.creationDate = o.creationDate;
        }
        this.deletedDate = o.deletedDate;
        if (o.passwordHistory != null && o.viewPassword !== false) {
            this.passwordHistory = o.passwordHistory.map((h) => new PasswordHistoryResponse(h));
        }
        if (o.type === CipherType.Login && o.login != null) {
            this.login = new LoginResponse(o.login, o.viewPassword);
        }
    }
}

;// ./src/admin-console/commands/share.command.ts
var share_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore





class ShareCommand {
    constructor(cipherService, accountService) {
        this.cipherService = cipherService;
        this.accountService = accountService;
    }
    run(id, organizationId, requestJson) {
        return share_command_awaiter(this, void 0, void 0, function* () {
            if (process.env.BW_SERVE !== "true" && (requestJson == null || requestJson === "")) {
                requestJson = yield CliUtils.readStdin();
            }
            if (requestJson == null || requestJson === "") {
                return response_Response.badRequest("`requestJson` was not provided.");
            }
            let req = [];
            if (typeof requestJson !== "string") {
                req = requestJson;
            }
            else {
                try {
                    const reqJson = Buffer.from(requestJson, "base64").toString();
                    req = JSON.parse(reqJson);
                    if (req == null || req.length === 0) {
                        return response_Response.badRequest("You must provide at least one collection id for this item.");
                    }
                    // FIXME: Remove when updating file. Eslint update
                    // eslint-disable-next-line @typescript-eslint/no-unused-vars
                }
                catch (e) {
                    return response_Response.badRequest("Error parsing the encoded request data.");
                }
            }
            if (id != null) {
                id = id.toLowerCase();
            }
            if (organizationId != null) {
                organizationId = organizationId.toLowerCase();
            }
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
            const cipher = yield this.cipherService.get(id, activeUserId);
            if (cipher == null) {
                return response_Response.notFound();
            }
            if (cipher.organizationId != null) {
                return response_Response.badRequest("This item already belongs to an organization.");
            }
            const cipherView = yield this.cipherService.decrypt(cipher, activeUserId);
            try {
                yield this.cipherService.shareWithServer(cipherView, organizationId, req, activeUserId);
                const updatedCipher = yield this.cipherService.get(cipher.id, activeUserId);
                const decCipher = yield this.cipherService.decrypt(updatedCipher, activeUserId);
                const res = new CipherResponse(decCipher);
                return response_Response.success(res);
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
}

;// ../../libs/common/src/admin-console/models/request/selection-read-only.request.ts
class selection_read_only_request_SelectionReadOnlyRequest {
    constructor(id, readOnly, hidePasswords, manage) {
        this.id = id;
        this.readOnly = readOnly;
        this.hidePasswords = hidePasswords;
        this.manage = manage;
    }
}

;// ../../libs/common/src/types/guid.ts

/**
 * A string representation of an empty guid.
 */
const emptyGuid = "00000000-0000-0000-0000-000000000000";
/**
 * Determines if the provided value is a valid GUID string.
 *
 * @typeParam SomeGuid - The input type, defaults to `Guid`.
 * @typeParam Output - The output type, resolves to `SomeGuid` if it is an opaque string, otherwise to `Guid` if `SomeGuid` is a string, or `never`.
 * @param id - The value to check.
 * @returns `true` if `id` is a string and a valid GUID, otherwise `false`.
 */
function isId(id) {
    return typeof id === "string" && isGuid(id);
}

;// ../../libs/common/src/models/export/collection.export.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore




class CollectionExport {
    static template() {
        const req = new CollectionExport();
        req.organizationId = emptyGuid;
        req.name = "Collection name";
        req.externalId = null;
        return req;
    }
    static toView(req, id) {
        const view = new CollectionView({
            name: req.name,
            organizationId: req.organizationId,
            id,
        });
        view.externalId = req.externalId;
        return view;
    }
    static toDomain(req, domain) {
        domain.name = req.name != null ? new enc_string_EncString(req.name) : null;
        domain.externalId = req.externalId;
        if (domain.organizationId == null) {
            domain.organizationId = req.organizationId;
        }
        return domain;
    }
    // Use build method instead of ctor so that we can control order of JSON stringify for pretty print
    build(o) {
        this.organizationId = o.organizationId;
        this.name = safeGetString(o.name);
        this.externalId = o.externalId;
    }
}

;// ../../libs/common/src/vault/models/view/folder.view.ts
class FolderView {
    constructor(f) {
        this.id = "";
        this.name = "";
        if (!f) {
            this.revisionDate = new Date();
            return;
        }
        this.id = f.id;
        this.revisionDate = f.revisionDate;
    }
    static fromJSON(obj) {
        var _a, _b;
        const folderView = new FolderView();
        folderView.id = (_a = obj.id) !== null && _a !== void 0 ? _a : "";
        folderView.name = (_b = obj.name) !== null && _b !== void 0 ? _b : "";
        if (obj.revisionDate != null) {
            folderView.revisionDate = new Date(obj.revisionDate);
        }
        return folderView;
    }
}

;// ../../libs/common/src/vault/models/domain/folder.ts
var folder_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};



class Folder extends Domain {
    constructor(obj) {
        super();
        this.id = "";
        this.name = new enc_string_EncString("");
        this.revisionDate = new Date();
        if (obj == null) {
            return;
        }
        this.id = obj.id;
        this.name = new enc_string_EncString(obj.name);
        this.revisionDate = new Date(obj.revisionDate);
    }
    decrypt(key) {
        return this.decryptObj(this, new FolderView(this), ["name"], key);
    }
    decryptWithKey(key, encryptService) {
        return folder_awaiter(this, void 0, void 0, function* () {
            const folderView = new FolderView();
            folderView.id = this.id;
            folderView.revisionDate = this.revisionDate;
            try {
                folderView.name = yield encryptService.decryptString(this.name, key);
            }
            catch (e) {
                // Note: This should be replaced by the owning team with appropriate, domain-specific behavior.
                // eslint-disable-next-line no-console
                console.error("[Folder] Error decrypting folder", e);
                throw e;
            }
            return folderView;
        });
    }
    static fromJSON(obj) {
        if (obj == null) {
            return null;
        }
        const folder = new Folder();
        folder.id = obj.id;
        folder.name = enc_string_EncString.fromJSON(obj.name);
        folder.revisionDate = new Date(obj.revisionDate);
        return folder;
    }
}

;// ../../libs/common/src/models/export/folder.export.ts




class FolderExport {
    constructor() {
        this.name = "";
    }
    static template() {
        const req = new FolderExport();
        req.name = "Folder name";
        return req;
    }
    static toView(req, view = new FolderView()) {
        view.name = req.name;
        return view;
    }
    static toDomain(req, domain = new Folder()) {
        domain.name = new enc_string_EncString(req.name);
        return domain;
    }
    // Use build method instead of ctor so that we can control order of JSON stringify for pretty print
    build(o) {
        var _a, _b;
        this.name = (_b = safeGetString((_a = o.name) !== null && _a !== void 0 ? _a : "")) !== null && _b !== void 0 ? _b : "";
    }
}

;// ../../libs/common/src/models/export/collection-with-id.export.ts

class CollectionWithIdExport extends CollectionExport {
    static toView(req) {
        return super.toView(req, req.id);
    }
    static toDomain(req, domain) {
        domain.id = req.id;
        return super.toDomain(req, domain);
    }
    // Use build method instead of ctor so that we can control order of JSON stringify for pretty print
    build(o) {
        this.id = o.id;
        super.build(o);
    }
}

;// ./src/admin-console/models/response/collection.response.ts

class collection_response_CollectionResponse extends CollectionWithIdExport {
    constructor(o) {
        super();
        this.object = "collection";
        this.build(o);
    }
}

;// ./src/admin-console/models/response/organization-collection.response.ts

class OrganizationCollectionResponse extends collection_response_CollectionResponse {
    constructor(o, groups, users) {
        super(o);
        this.object = "org-collection";
        this.groups = groups;
        this.users = users;
    }
}

;// ../../libs/common/src/models/export/folder-with-id.export.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore



class FolderWithIdExport extends FolderExport {
    static toView(req, view = new FolderView()) {
        view.id = req.id;
        return super.toView(req, view);
    }
    static toDomain(req, domain = new Folder()) {
        domain.id = req.id;
        return super.toDomain(req, domain);
    }
    // Use build method instead of ctor so that we can control order of JSON stringify for pretty print
    build(o) {
        this.id = o.id;
        super.build(o);
    }
}

;// ../../libs/common/src/models/export/index.ts













;// ./src/vault/models/folder.response.ts

class FolderResponse extends FolderWithIdExport {
    constructor(o) {
        super();
        this.object = "folder";
        this.build(o);
    }
}

;// ./src/commands/edit.command.ts
var commands_edit_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
















class EditCommand {
    constructor(cipherService, folderService, keyService, encryptService, apiService, folderApiService, accountService, cliRestrictedItemTypesService, policyService, billingAccountProfileStateService) {
        this.cipherService = cipherService;
        this.folderService = folderService;
        this.keyService = keyService;
        this.encryptService = encryptService;
        this.apiService = apiService;
        this.folderApiService = folderApiService;
        this.accountService = accountService;
        this.cliRestrictedItemTypesService = cliRestrictedItemTypesService;
        this.policyService = policyService;
        this.billingAccountProfileStateService = billingAccountProfileStateService;
    }
    run(object, id, requestJson, cmdOptions) {
        return commands_edit_command_awaiter(this, void 0, void 0, function* () {
            if (process.env.BW_SERVE !== "true" && (requestJson == null || requestJson === "")) {
                requestJson = yield CliUtils.readStdin();
            }
            if (requestJson == null || requestJson === "") {
                return response_Response.badRequest("`requestJson` was not provided.");
            }
            let req = null;
            if (typeof requestJson !== "string") {
                req = requestJson;
            }
            else {
                try {
                    const reqJson = Buffer.from(requestJson, "base64").toString();
                    req = JSON.parse(reqJson);
                    // FIXME: Remove when updating file. Eslint update
                    // eslint-disable-next-line @typescript-eslint/no-unused-vars
                }
                catch (e) {
                    return response_Response.badRequest("Error parsing the encoded request data.");
                }
            }
            if (id != null) {
                id = id.toLowerCase();
            }
            const normalizedOptions = new commands_edit_command_Options(cmdOptions);
            switch (object.toLowerCase()) {
                case "item":
                    return yield this.editCipher(id, req);
                case "item-collections":
                    return yield this.editCipherCollections(id, req);
                case "folder":
                    return yield this.editFolder(id, req);
                case "org-collection":
                    return yield this.editOrganizationCollection(id, req, normalizedOptions);
                default:
                    return response_Response.badRequest("Unknown object.");
            }
        });
    }
    editCipher(id, req) {
        return commands_edit_command_awaiter(this, void 0, void 0, function* () {
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
            const cipher = yield this.cipherService.get(id, activeUserId);
            const hasPremium = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.billingAccountProfileStateService.hasPremiumFromAnySource$(activeUserId));
            if (cipher == null) {
                return response_Response.notFound();
            }
            let cipherView = yield this.cipherService.decrypt(cipher, activeUserId);
            if (cipherView.isDeleted) {
                return response_Response.badRequest("You may not edit a deleted item. Use the restore command first.");
            }
            cipherView = CipherExport.toView(req, cipherView);
            // When a user is editing an archived cipher and does not have premium, automatically unarchive it
            if (cipherView.isArchived && !hasPremium) {
                const acceptedPrompt = yield this.promptForArchiveEdit();
                if (!acceptedPrompt) {
                    return response_Response.error("Edit cancelled.");
                }
                cipherView.archivedDate = null;
            }
            const isCipherRestricted = yield this.cliRestrictedItemTypesService.isCipherRestricted(cipherView);
            if (isCipherRestricted) {
                return response_Response.error("Editing this item type is restricted by organizational policy.");
            }
            const isPersonalVaultItem = cipherView.organizationId == null;
            const organizationOwnershipPolicyApplies = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.policyService.policyAppliesToUser$(policy_type_enum_PolicyType.OrganizationDataOwnership, activeUserId));
            if (isPersonalVaultItem && organizationOwnershipPolicyApplies) {
                return response_Response.error("An organization policy restricts editing this cipher. Please use the share command first before modifying it.");
            }
            try {
                const decCipher = yield this.cipherService.updateWithServer(cipherView, activeUserId);
                const res = new CipherResponse(decCipher);
                return response_Response.success(res);
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
    editCipherCollections(id, req) {
        return commands_edit_command_awaiter(this, void 0, void 0, function* () {
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
            const cipher = yield this.cipherService.get(id, activeUserId);
            if (cipher == null) {
                return response_Response.notFound();
            }
            if (cipher.organizationId == null) {
                return response_Response.badRequest("Item does not belong to an organization. Consider moving it first.");
            }
            if (!cipher.viewPassword) {
                return response_Response.noEditPermission();
            }
            cipher.collectionIds = req;
            try {
                const updatedCipher = yield this.cipherService.saveCollectionsWithServer(cipher, activeUserId);
                const decCipher = yield this.cipherService.decrypt(updatedCipher, activeUserId);
                const res = new CipherResponse(decCipher);
                return response_Response.success(res);
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
    editFolder(id, req) {
        return commands_edit_command_awaiter(this, void 0, void 0, function* () {
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
            const folder = yield this.folderService.getFromState(id, activeUserId);
            if (folder == null) {
                return response_Response.notFound();
            }
            const userKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.userKey$(activeUserId));
            let folderView = yield folder.decrypt(userKey);
            folderView = FolderExport.toView(req, folderView);
            const encFolder = yield this.folderService.encrypt(folderView, userKey);
            try {
                const folder = yield this.folderApiService.save(encFolder, activeUserId);
                const updatedFolder = new Folder(folder);
                const decFolder = yield updatedFolder.decrypt(userKey);
                const res = new FolderResponse(decFolder);
                return response_Response.success(res);
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
    editOrganizationCollection(id, req, options) {
        return commands_edit_command_awaiter(this, void 0, void 0, function* () {
            if (options.organizationId == null || options.organizationId === "") {
                return response_Response.badRequest("`organizationid` option is required.");
            }
            if (!utils_Utils.isGuid(id)) {
                return response_Response.badRequest("`" + id + "` is not a GUID.");
            }
            if (!utils_Utils.isGuid(options.organizationId)) {
                return response_Response.badRequest("`" + options.organizationId + "` is not a GUID.");
            }
            if (options.organizationId !== req.organizationId) {
                return response_Response.badRequest("`organizationid` option does not match request object.");
            }
            if (req.name == null || req.name.trim() === "") {
                return response_Response.badRequest("Collection name is required.");
            }
            try {
                const orgKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId, (0,external_rxjs_namespaceObject.switchMap)((userId) => this.keyService.orgKeys$(userId)), (0,external_rxjs_namespaceObject.map)((orgKeys) => { var _a; return (_a = orgKeys[options.organizationId]) !== null && _a !== void 0 ? _a : null; })));
                if (orgKey == null) {
                    throw new Error("No encryption key for this organization.");
                }
                const groups = req.groups == null
                    ? null
                    : req.groups.map((g) => new selection_read_only_request_SelectionReadOnlyRequest(g.id, g.readOnly, g.hidePasswords, g.manage));
                const users = req.users == null
                    ? null
                    : req.users.map((u) => new selection_read_only_request_SelectionReadOnlyRequest(u.id, u.readOnly, u.hidePasswords, u.manage));
                const request = new collection_request_UpdateCollectionRequest({
                    name: yield this.encryptService.encryptString(req.name, orgKey),
                    externalId: req.externalId,
                    users,
                    groups,
                });
                const response = yield this.apiService.putCollection(req.organizationId, id, request);
                const view = CollectionExport.toView(req, response.id);
                const res = new OrganizationCollectionResponse(view, groups, users);
                return response_Response.success(res);
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
    /** Prompt the user to accept movement of their cipher back to the their vault. */
    promptForArchiveEdit() {
        return commands_edit_command_awaiter(this, void 0, void 0, function* () {
            // When user has disabled interactivity or does not have the ability to prompt,
            // automatically move the item back to the vault and inform them.
            if (process.env.BW_SERVE === "true" ||
                process.env.BW_NOINTERACTION === "true" ||
                !process.stdin.isTTY) {
                CliUtils.writeLn("Archive is only available with a Premium subscription, which has ended. Your edit was saved and the item was moved back to your vault.");
                return true;
            }
            const answer = yield external_inquirer_namespaceObject.createPromptModule({
                output: process.stderr,
            })({
                type: "list",
                name: "confirm",
                message: "When you edit and save details for an archived item without a Premium subscription, it'll be moved from your archive back to your vault.",
                choices: [
                    {
                        name: "Move now",
                        value: "confirmed",
                    },
                    {
                        name: "Cancel",
                        value: "cancel",
                    },
                ],
            });
            return answer.confirm === "confirmed";
        });
    }
}
class commands_edit_command_Options {
    constructor(passedOptions) {
        this.organizationId = (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.organizationid) || (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.organizationId);
    }
}

;// ../../libs/common/src/dirt/event-logs/enums/event-type.enum.ts
// Increment by 100 for each new set of events
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var EventType;
(function (EventType) {
    EventType[EventType["User_LoggedIn"] = 1000] = "User_LoggedIn";
    EventType[EventType["User_ChangedPassword"] = 1001] = "User_ChangedPassword";
    EventType[EventType["User_Updated2fa"] = 1002] = "User_Updated2fa";
    EventType[EventType["User_Disabled2fa"] = 1003] = "User_Disabled2fa";
    EventType[EventType["User_Recovered2fa"] = 1004] = "User_Recovered2fa";
    EventType[EventType["User_FailedLogIn"] = 1005] = "User_FailedLogIn";
    EventType[EventType["User_FailedLogIn2fa"] = 1006] = "User_FailedLogIn2fa";
    EventType[EventType["User_ClientExportedVault"] = 1007] = "User_ClientExportedVault";
    EventType[EventType["User_UpdatedTempPassword"] = 1008] = "User_UpdatedTempPassword";
    EventType[EventType["User_MigratedKeyToKeyConnector"] = 1009] = "User_MigratedKeyToKeyConnector";
    EventType[EventType["User_RequestedDeviceApproval"] = 1010] = "User_RequestedDeviceApproval";
    EventType[EventType["User_TdeOffboardingPasswordSet"] = 1011] = "User_TdeOffboardingPasswordSet";
    EventType[EventType["Cipher_Created"] = 1100] = "Cipher_Created";
    EventType[EventType["Cipher_Updated"] = 1101] = "Cipher_Updated";
    EventType[EventType["Cipher_Deleted"] = 1102] = "Cipher_Deleted";
    EventType[EventType["Cipher_AttachmentCreated"] = 1103] = "Cipher_AttachmentCreated";
    EventType[EventType["Cipher_AttachmentDeleted"] = 1104] = "Cipher_AttachmentDeleted";
    EventType[EventType["Cipher_Shared"] = 1105] = "Cipher_Shared";
    EventType[EventType["Cipher_UpdatedCollections"] = 1106] = "Cipher_UpdatedCollections";
    EventType[EventType["Cipher_ClientViewed"] = 1107] = "Cipher_ClientViewed";
    EventType[EventType["Cipher_ClientToggledPasswordVisible"] = 1108] = "Cipher_ClientToggledPasswordVisible";
    EventType[EventType["Cipher_ClientToggledHiddenFieldVisible"] = 1109] = "Cipher_ClientToggledHiddenFieldVisible";
    EventType[EventType["Cipher_ClientToggledCardCodeVisible"] = 1110] = "Cipher_ClientToggledCardCodeVisible";
    EventType[EventType["Cipher_ClientCopiedPassword"] = 1111] = "Cipher_ClientCopiedPassword";
    EventType[EventType["Cipher_ClientCopiedHiddenField"] = 1112] = "Cipher_ClientCopiedHiddenField";
    EventType[EventType["Cipher_ClientCopiedCardCode"] = 1113] = "Cipher_ClientCopiedCardCode";
    EventType[EventType["Cipher_ClientAutofilled"] = 1114] = "Cipher_ClientAutofilled";
    EventType[EventType["Cipher_SoftDeleted"] = 1115] = "Cipher_SoftDeleted";
    EventType[EventType["Cipher_Restored"] = 1116] = "Cipher_Restored";
    EventType[EventType["Cipher_ClientToggledCardNumberVisible"] = 1117] = "Cipher_ClientToggledCardNumberVisible";
    EventType[EventType["Cipher_ClientToggledTOTPSeedVisible"] = 1118] = "Cipher_ClientToggledTOTPSeedVisible";
    EventType[EventType["Collection_Created"] = 1300] = "Collection_Created";
    EventType[EventType["Collection_Updated"] = 1301] = "Collection_Updated";
    EventType[EventType["Collection_Deleted"] = 1302] = "Collection_Deleted";
    EventType[EventType["Group_Created"] = 1400] = "Group_Created";
    EventType[EventType["Group_Updated"] = 1401] = "Group_Updated";
    EventType[EventType["Group_Deleted"] = 1402] = "Group_Deleted";
    EventType[EventType["OrganizationUser_Invited"] = 1500] = "OrganizationUser_Invited";
    EventType[EventType["OrganizationUser_Confirmed"] = 1501] = "OrganizationUser_Confirmed";
    EventType[EventType["OrganizationUser_Updated"] = 1502] = "OrganizationUser_Updated";
    EventType[EventType["OrganizationUser_Removed"] = 1503] = "OrganizationUser_Removed";
    EventType[EventType["OrganizationUser_UpdatedGroups"] = 1504] = "OrganizationUser_UpdatedGroups";
    EventType[EventType["OrganizationUser_UnlinkedSso"] = 1505] = "OrganizationUser_UnlinkedSso";
    EventType[EventType["OrganizationUser_ResetPassword_Enroll"] = 1506] = "OrganizationUser_ResetPassword_Enroll";
    EventType[EventType["OrganizationUser_ResetPassword_Withdraw"] = 1507] = "OrganizationUser_ResetPassword_Withdraw";
    EventType[EventType["OrganizationUser_AdminResetPassword"] = 1508] = "OrganizationUser_AdminResetPassword";
    EventType[EventType["OrganizationUser_ResetSsoLink"] = 1509] = "OrganizationUser_ResetSsoLink";
    EventType[EventType["OrganizationUser_FirstSsoLogin"] = 1510] = "OrganizationUser_FirstSsoLogin";
    EventType[EventType["OrganizationUser_Revoked"] = 1511] = "OrganizationUser_Revoked";
    EventType[EventType["OrganizationUser_Restored"] = 1512] = "OrganizationUser_Restored";
    EventType[EventType["OrganizationUser_ApprovedAuthRequest"] = 1513] = "OrganizationUser_ApprovedAuthRequest";
    EventType[EventType["OrganizationUser_RejectedAuthRequest"] = 1514] = "OrganizationUser_RejectedAuthRequest";
    EventType[EventType["OrganizationUser_Deleted"] = 1515] = "OrganizationUser_Deleted";
    EventType[EventType["OrganizationUser_Left"] = 1516] = "OrganizationUser_Left";
    EventType[EventType["OrganizationUser_AutomaticallyConfirmed"] = 1517] = "OrganizationUser_AutomaticallyConfirmed";
    EventType[EventType["OrganizationUser_SelfRevoked"] = 1518] = "OrganizationUser_SelfRevoked";
    EventType[EventType["OrganizationUser_AdminResetTwoFactor"] = 1519] = "OrganizationUser_AdminResetTwoFactor";
    EventType[EventType["Organization_Updated"] = 1600] = "Organization_Updated";
    EventType[EventType["Organization_PurgedVault"] = 1601] = "Organization_PurgedVault";
    EventType[EventType["Organization_ClientExportedVault"] = 1602] = "Organization_ClientExportedVault";
    EventType[EventType["Organization_VaultAccessed"] = 1603] = "Organization_VaultAccessed";
    EventType[EventType["Organization_EnabledSso"] = 1604] = "Organization_EnabledSso";
    EventType[EventType["Organization_DisabledSso"] = 1605] = "Organization_DisabledSso";
    EventType[EventType["Organization_EnabledKeyConnector"] = 1606] = "Organization_EnabledKeyConnector";
    EventType[EventType["Organization_DisabledKeyConnector"] = 1607] = "Organization_DisabledKeyConnector";
    EventType[EventType["Organization_SponsorshipsSynced"] = 1608] = "Organization_SponsorshipsSynced";
    EventType[EventType["Organization_CollectionManagementUpdated"] = 1609] = "Organization_CollectionManagementUpdated";
    EventType[EventType["Organization_CollectionManagement_LimitCollectionCreationEnabled"] = 1610] = "Organization_CollectionManagement_LimitCollectionCreationEnabled";
    EventType[EventType["Organization_CollectionManagement_LimitCollectionCreationDisabled"] = 1611] = "Organization_CollectionManagement_LimitCollectionCreationDisabled";
    EventType[EventType["Organization_CollectionManagement_LimitCollectionDeletionEnabled"] = 1612] = "Organization_CollectionManagement_LimitCollectionDeletionEnabled";
    EventType[EventType["Organization_CollectionManagement_LimitCollectionDeletionDisabled"] = 1613] = "Organization_CollectionManagement_LimitCollectionDeletionDisabled";
    EventType[EventType["Organization_CollectionManagement_LimitItemDeletionEnabled"] = 1614] = "Organization_CollectionManagement_LimitItemDeletionEnabled";
    EventType[EventType["Organization_CollectionManagement_LimitItemDeletionDisabled"] = 1615] = "Organization_CollectionManagement_LimitItemDeletionDisabled";
    EventType[EventType["Organization_CollectionManagement_AllowAdminAccessToAllCollectionItemsEnabled"] = 1616] = "Organization_CollectionManagement_AllowAdminAccessToAllCollectionItemsEnabled";
    EventType[EventType["Organization_CollectionManagement_AllowAdminAccessToAllCollectionItemsDisabled"] = 1617] = "Organization_CollectionManagement_AllowAdminAccessToAllCollectionItemsDisabled";
    EventType[EventType["Organization_ItemOrganization_Accepted"] = 1618] = "Organization_ItemOrganization_Accepted";
    EventType[EventType["Organization_ItemOrganization_Declined"] = 1619] = "Organization_ItemOrganization_Declined";
    EventType[EventType["Organization_AutoConfirmEnabled_Admin"] = 1620] = "Organization_AutoConfirmEnabled_Admin";
    EventType[EventType["Organization_AutoConfirmDisabled_Admin"] = 1621] = "Organization_AutoConfirmDisabled_Admin";
    EventType[EventType["Organization_AutoConfirmEnabled_Portal"] = 1622] = "Organization_AutoConfirmEnabled_Portal";
    EventType[EventType["Organization_AutoConfirmDisabled_Portal"] = 1623] = "Organization_AutoConfirmDisabled_Portal";
    EventType[EventType["Policy_Updated"] = 1700] = "Policy_Updated";
    EventType[EventType["ProviderUser_Invited"] = 1800] = "ProviderUser_Invited";
    EventType[EventType["ProviderUser_Confirmed"] = 1801] = "ProviderUser_Confirmed";
    EventType[EventType["ProviderUser_Updated"] = 1802] = "ProviderUser_Updated";
    EventType[EventType["ProviderUser_Removed"] = 1803] = "ProviderUser_Removed";
    EventType[EventType["ProviderOrganization_Created"] = 1900] = "ProviderOrganization_Created";
    EventType[EventType["ProviderOrganization_Added"] = 1901] = "ProviderOrganization_Added";
    EventType[EventType["ProviderOrganization_Removed"] = 1902] = "ProviderOrganization_Removed";
    EventType[EventType["ProviderOrganization_VaultAccessed"] = 1903] = "ProviderOrganization_VaultAccessed";
    EventType[EventType["OrganizationDomain_Added"] = 2000] = "OrganizationDomain_Added";
    EventType[EventType["OrganizationDomain_Removed"] = 2001] = "OrganizationDomain_Removed";
    EventType[EventType["OrganizationDomain_Verified"] = 2002] = "OrganizationDomain_Verified";
    EventType[EventType["OrganizationDomain_NotVerified"] = 2003] = "OrganizationDomain_NotVerified";
    EventType[EventType["Secret_Retrieved"] = 2100] = "Secret_Retrieved";
    EventType[EventType["Secret_Created"] = 2101] = "Secret_Created";
    EventType[EventType["Secret_Edited"] = 2102] = "Secret_Edited";
    EventType[EventType["Secret_Deleted"] = 2103] = "Secret_Deleted";
    EventType[EventType["Secret_Permanently_Deleted"] = 2104] = "Secret_Permanently_Deleted";
    EventType[EventType["Secret_Restored"] = 2105] = "Secret_Restored";
    EventType[EventType["Project_Retrieved"] = 2200] = "Project_Retrieved";
    EventType[EventType["Project_Created"] = 2201] = "Project_Created";
    EventType[EventType["Project_Edited"] = 2202] = "Project_Edited";
    EventType[EventType["Project_Deleted"] = 2203] = "Project_Deleted";
    EventType[EventType["ServiceAccount_UserAdded"] = 2300] = "ServiceAccount_UserAdded";
    EventType[EventType["ServiceAccount_UserRemoved"] = 2301] = "ServiceAccount_UserRemoved";
    EventType[EventType["ServiceAccount_GroupAdded"] = 2302] = "ServiceAccount_GroupAdded";
    EventType[EventType["ServiceAccount_GroupRemoved"] = 2303] = "ServiceAccount_GroupRemoved";
    EventType[EventType["ServiceAccount_Created"] = 2304] = "ServiceAccount_Created";
    EventType[EventType["ServiceAccount_Deleted"] = 2305] = "ServiceAccount_Deleted";
    EventType[EventType["PhishingBlocker_SiteAccessed"] = 2400] = "PhishingBlocker_SiteAccessed";
    EventType[EventType["PhishingBlocker_SiteExited"] = 2401] = "PhishingBlocker_SiteExited";
    EventType[EventType["PhishingBlocker_Bypassed"] = 2402] = "PhishingBlocker_Bypassed";
})(EventType || (EventType = {}));

;// ../../libs/common/src/dirt/event-logs/enums/event-system-user.enum.ts
// Note: the enum key is used to describe the EventSystemUser in the UI. Be careful about changing it.
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var EventSystemUser;
(function (EventSystemUser) {
    EventSystemUser[EventSystemUser["SCIM"] = 1] = "SCIM";
    EventSystemUser[EventSystemUser["DomainVerification"] = 2] = "DomainVerification";
    EventSystemUser[EventSystemUser["PublicApi"] = 3] = "PublicApi";
    EventSystemUser[EventSystemUser["BitwardenPortal"] = 5] = "BitwardenPortal";
})(EventSystemUser || (EventSystemUser = {}));

;// ../../libs/common/src/dirt/event-logs/enums/event-category.enum.ts

const EventCategory = {
    UserEvents: "userEvents",
    ItemEvents: "itemEvents",
    CollectionEvents: "collectionEvents",
    GroupEvents: "groupEvents",
    OrganizationMemberEvents: "organizationMemberEvents",
    OrganizationEvents: "organizationEvents",
    ProviderEvents: "providerEvents",
};
const EventCategoryEventTypes = {
    [EventCategory.UserEvents]: [
        EventType.User_LoggedIn,
        EventType.User_ChangedPassword,
        EventType.User_Updated2fa,
        EventType.User_Disabled2fa,
        EventType.User_Recovered2fa,
        EventType.User_FailedLogIn,
        EventType.User_FailedLogIn2fa,
        EventType.User_ClientExportedVault,
        EventType.User_UpdatedTempPassword,
        EventType.User_MigratedKeyToKeyConnector,
        EventType.User_RequestedDeviceApproval,
        EventType.User_TdeOffboardingPasswordSet,
    ],
    [EventCategory.ItemEvents]: [
        EventType.Cipher_Created,
        EventType.Cipher_Updated,
        EventType.Cipher_Deleted,
        EventType.Cipher_AttachmentCreated,
        EventType.Cipher_AttachmentDeleted,
        EventType.Cipher_Shared,
        EventType.Cipher_UpdatedCollections,
        EventType.Cipher_ClientViewed,
        EventType.Cipher_ClientToggledPasswordVisible,
        EventType.Cipher_ClientToggledHiddenFieldVisible,
        EventType.Cipher_ClientToggledCardCodeVisible,
        EventType.Cipher_ClientCopiedPassword,
        EventType.Cipher_ClientCopiedHiddenField,
        EventType.Cipher_ClientCopiedCardCode,
        EventType.Cipher_ClientAutofilled,
        EventType.Cipher_SoftDeleted,
        EventType.Cipher_Restored,
        EventType.Cipher_ClientToggledCardNumberVisible,
        EventType.Cipher_ClientToggledTOTPSeedVisible,
    ],
    [EventCategory.CollectionEvents]: [
        EventType.Collection_Created,
        EventType.Collection_Updated,
        EventType.Collection_Deleted,
    ],
    [EventCategory.GroupEvents]: [
        EventType.Group_Created,
        EventType.Group_Updated,
        EventType.Group_Deleted,
    ],
    [EventCategory.OrganizationMemberEvents]: [
        EventType.OrganizationUser_Invited,
        EventType.OrganizationUser_Confirmed,
        EventType.OrganizationUser_Updated,
        EventType.OrganizationUser_Removed,
        EventType.OrganizationUser_UpdatedGroups,
        EventType.OrganizationUser_UnlinkedSso,
        EventType.OrganizationUser_ResetPassword_Enroll,
        EventType.OrganizationUser_ResetPassword_Withdraw,
        EventType.OrganizationUser_AdminResetPassword,
        EventType.OrganizationUser_AdminResetTwoFactor,
        EventType.OrganizationUser_ResetSsoLink,
        EventType.OrganizationUser_FirstSsoLogin,
        EventType.OrganizationUser_Revoked,
        EventType.OrganizationUser_Restored,
        EventType.OrganizationUser_ApprovedAuthRequest,
        EventType.OrganizationUser_RejectedAuthRequest,
        EventType.OrganizationUser_Deleted,
        EventType.OrganizationUser_Left,
        EventType.OrganizationUser_SelfRevoked,
    ],
    [EventCategory.OrganizationEvents]: [
        EventType.Organization_Updated,
        EventType.Organization_PurgedVault,
        EventType.Organization_ClientExportedVault,
        EventType.Organization_VaultAccessed,
        EventType.Organization_EnabledSso,
        EventType.Organization_DisabledSso,
        EventType.Organization_EnabledKeyConnector,
        EventType.Organization_DisabledKeyConnector,
        EventType.Organization_SponsorshipsSynced,
        EventType.Organization_CollectionManagementUpdated,
        EventType.Organization_CollectionManagement_LimitCollectionCreationEnabled,
        EventType.Organization_CollectionManagement_LimitCollectionCreationDisabled,
        EventType.Organization_CollectionManagement_LimitCollectionDeletionEnabled,
        EventType.Organization_CollectionManagement_LimitCollectionDeletionDisabled,
        EventType.Organization_CollectionManagement_LimitItemDeletionEnabled,
        EventType.Organization_CollectionManagement_LimitItemDeletionDisabled,
        EventType.Organization_CollectionManagement_AllowAdminAccessToAllCollectionItemsEnabled,
        EventType.Organization_CollectionManagement_AllowAdminAccessToAllCollectionItemsDisabled,
    ],
    [EventCategory.ProviderEvents]: [
        EventType.ProviderUser_Invited,
        EventType.ProviderUser_Confirmed,
        EventType.ProviderUser_Updated,
        EventType.ProviderUser_Removed,
        EventType.ProviderOrganization_Created,
        EventType.ProviderOrganization_Added,
        EventType.ProviderOrganization_Removed,
        EventType.ProviderOrganization_VaultAccessed,
    ],
};

;// ../../libs/common/src/dirt/event-logs/models/response/event.response.ts

class EventResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.type = this.getResponseProperty("Type");
        this.userId = this.getResponseProperty("UserId");
        this.organizationId = this.getResponseProperty("OrganizationId");
        this.providerId = this.getResponseProperty("ProviderId");
        this.cipherId = this.getResponseProperty("CipherId");
        this.collectionId = this.getResponseProperty("CollectionId");
        this.groupId = this.getResponseProperty("GroupId");
        this.policyId = this.getResponseProperty("PolicyId");
        this.organizationUserId = this.getResponseProperty("OrganizationUserId");
        this.providerUserId = this.getResponseProperty("ProviderUserId");
        this.providerOrganizationId = this.getResponseProperty("ProviderOrganizationId");
        this.actingUserId = this.getResponseProperty("ActingUserId");
        this.date = this.getResponseProperty("Date");
        this.deviceType = this.getResponseProperty("DeviceType");
        this.ipAddress = this.getResponseProperty("IpAddress");
        this.installationId = this.getResponseProperty("InstallationId");
        this.systemUser = this.getResponseProperty("SystemUser");
        this.domainName = this.getResponseProperty("DomainName");
        this.secretId = this.getResponseProperty("SecretId");
        this.projectId = this.getResponseProperty("ProjectId");
        this.serviceAccountId = this.getResponseProperty("ServiceAccountId");
        this.grantedServiceAccountId = this.getResponseProperty("GrantedServiceAccountId");
    }
}

;// ../../libs/common/src/dirt/event-logs/models/data/event.data.ts
class EventData {
    static fromJSON(obj) {
        return Object.assign(new EventData(), obj);
    }
}

;// ../../libs/common/src/dirt/event-logs/services/key-definitions.ts


const key_definitions_EVENT_COLLECTION = UserKeyDefinition.array(EVENT_COLLECTION_DISK, "events", {
    deserializer: (s) => EventData.fromJSON(s),
    clearOn: ["logout"],
});

;// ../../libs/common/src/dirt/event-logs/index.ts
// Enums



// Models




// Abstractions (export abstract classes)




;// ../../libs/common/src/platform/misc/rxjs-operators.ts

/**
 * An rxjs operator that extracts an object by ID from an array of objects.
 * @param id The ID of the object to return.
 * @returns The first object with a matching ID, or undefined if no matching object is present.
 */
const getById = (id) => (0,external_rxjs_namespaceObject.map)((objects) => objects.find((o) => o.id === id));
/**
 * An rxjs operator that extracts a subset of objects by their IDs from an array of objects.
 * @param id The IDs of the objects to return.
 * @returns An array containing objects with matching IDs, or an empty array if there are no matching objects.
 */
const getByIds = (ids) => {
    const idSet = new Set(ids);
    return (0,external_rxjs_namespaceObject.map)((objects) => {
        return objects.filter((o) => o.id && idSet.has(o.id));
    });
};
/**
 * A merge-like operator that takes a Set of primitives and tracks if they've been
 * seen before.
 *
 * An emitted set that looks like `["1", "2"]` will call selector and subscribe to the resulting
 * observable for both `"1"` and `"2"` but if the next emission contains just `["1"]` then the
 * subscription created for `"2"` will be unsubscribed from and the observable for `"1"` will be
 * left alone. If the following emission a set like `["1", "2", "3"]` then the subscription for
 * `"1"` is still left alone, `"2"` has a selector called for it again, and `"3"` has a selector
 * called for it the first time. If an empty set is emitted then all items are unsubscribed from.
 *
 * Since this operator will keep track of an observable for `n` number of items given to it. It is
 * smartest to only use this on sets that you know will only get so large.
 *
 * *IMPORTANT NOTE*
 * This observable may not be super friendly to very quick emissions/near parallel execution.
 */
function trackedMerge(selector) {
    return (source) => {
        // Setup a Map to track all inner subscriptions
        const tracked = new Map();
        const cleanupTracked = () => {
            for (const [, trackedSub] of tracked.entries()) {
                trackedSub.unsubscribe();
            }
            tracked.clear();
        };
        return new Observable((subscriber) => {
            const sourceSub = source.subscribe({
                next: (values) => {
                    var _a;
                    // Loop through the subscriptions we are tracking, if the new list
                    // doesn't have any of those values, we should clean them up.
                    for (const value of tracked.keys()) {
                        if (!values.has(value)) {
                            // Tracked item is no longer in the list, cleanup
                            (_a = tracked.get(value)) === null || _a === void 0 ? void 0 : _a.unsubscribe();
                            tracked.delete(value);
                            continue;
                        }
                        // We are already tracking something for this key, remove it
                        values.delete(value);
                    }
                    for (const newKey of values.keys()) {
                        // These are new entries, create and track subscription for them
                        tracked.set(newKey, 
                        /* eslint-disable-next-line rxjs/no-nested-subscribe */
                        selector(newKey).subscribe({
                            next: (innerValue) => {
                                subscriber.next(innerValue);
                            },
                            error: (err) => {
                                // TODO: Do I need to call cleanupTracked or will calling error run my teardown logic below?
                                subscriber.error(err);
                            },
                            complete: () => {
                                tracked.delete(newKey);
                            },
                        }));
                    }
                },
                error: (err) => {
                    // TODO: Do I need to call cleanupTracked or will calling error run my teardown logic below?
                    subscriber.error(err);
                },
                complete: () => {
                    // TODO: Do I need to call cleanupTracked or will calling complete run my teardown logic below?
                    cleanupTracked();
                    subscriber.complete();
                },
            });
            return () => {
                cleanupTracked();
                sourceSub.unsubscribe();
            };
        });
    };
}

;// ../../libs/common/src/platform/misc/index.ts


;// ./src/admin-console/models/selection-read-only.ts
class SelectionReadOnly {
    static template() {
        return new SelectionReadOnly("00000000-0000-0000-0000-000000000000", false, false, false);
    }
    constructor(id, readOnly, hidePasswords, manage) {
        this.id = id;
        this.readOnly = readOnly;
        this.hidePasswords = hidePasswords || false;
        this.manage = manage;
    }
}

;// ./src/admin-console/models/request/organization-collection.request.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


class OrganizationCollectionRequest extends CollectionExport {
    static template() {
        const req = new OrganizationCollectionRequest();
        req.organizationId = "00000000-0000-0000-0000-000000000000";
        req.name = "Collection name";
        req.externalId = null;
        req.groups = [SelectionReadOnly.template(), SelectionReadOnly.template()];
        req.users = [SelectionReadOnly.template(), SelectionReadOnly.template()];
        return req;
    }
}

;// ./src/admin-console/models/response/organization.response.ts
class OrganizationResponse {
    constructor(o) {
        this.object = "organization";
        this.id = o.id;
        this.name = o.name;
        this.status = o.status;
        this.type = o.type;
        this.enabled = o.enabled;
    }
}

;// ./src/commands/get.command.ts
var commands_get_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore





























class GetCommand extends DownloadCommand {
    constructor(cipherService, folderService, collectionService, totpService, auditService, keyService, encryptService, searchService, apiService, organizationService, eventCollectionService, accountProfileService, accountService, cliRestrictedItemTypesService) {
        super(encryptService, apiService);
        this.cipherService = cipherService;
        this.folderService = folderService;
        this.collectionService = collectionService;
        this.totpService = totpService;
        this.auditService = auditService;
        this.keyService = keyService;
        this.searchService = searchService;
        this.apiService = apiService;
        this.organizationService = organizationService;
        this.eventCollectionService = eventCollectionService;
        this.accountProfileService = accountProfileService;
        this.accountService = accountService;
        this.cliRestrictedItemTypesService = cliRestrictedItemTypesService;
    }
    run(object, id, cmdOptions) {
        return commands_get_command_awaiter(this, void 0, void 0, function* () {
            if (id != null) {
                id = id.toLowerCase();
            }
            const normalizedOptions = new get_command_Options(cmdOptions);
            switch (object.toLowerCase()) {
                case "item":
                    return yield this.getCipher(id);
                case "username":
                    return yield this.getUsername(id);
                case "password":
                    return yield this.getPassword(id);
                case "uri":
                    return yield this.getUri(id);
                case "totp":
                    return yield this.getTotp(id);
                case "notes":
                    return yield this.getNotes(id);
                case "exposed":
                    return yield this.getExposed(id);
                case "attachment":
                    return yield this.getAttachment(id, normalizedOptions);
                case "folder":
                    return yield this.getFolder(id);
                case "collection":
                    return yield this.getCollection(id);
                case "org-collection":
                    return yield this.getOrganizationCollection(id, normalizedOptions);
                case "organization":
                    return yield this.getOrganization(id);
                case "template":
                    return yield this.getTemplate(id);
                case "fingerprint":
                    return yield this.getFingerprint(id);
                default:
                    return response_Response.badRequest("Unknown object.");
            }
        });
    }
    getCipherView(id, userId) {
        return commands_get_command_awaiter(this, void 0, void 0, function* () {
            let decCipher = null;
            if (utils_Utils.isGuid(id)) {
                const cipher = yield this.cipherService.get(id, userId);
                if (cipher != null) {
                    decCipher = yield this.cipherService.decrypt(cipher, userId);
                }
            }
            else if (id.trim() !== "") {
                let ciphers = yield this.cipherService.getAllDecrypted(userId);
                ciphers = this.searchService.searchCiphersBasic(ciphers, id);
                if (ciphers.length > 1) {
                    return ciphers;
                }
                if (ciphers.length > 0) {
                    decCipher = ciphers[0];
                }
            }
            return decCipher;
        });
    }
    getCipher(id, filter) {
        return commands_get_command_awaiter(this, void 0, void 0, function* () {
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
            let decCipher = yield this.getCipherView(id, activeUserId);
            if (decCipher == null) {
                return response_Response.notFound();
            }
            if (Array.isArray(decCipher)) {
                // Apply restricted ciphers filter
                decCipher = yield this.cliRestrictedItemTypesService.filterRestrictedCiphers(decCipher);
                if (decCipher.length === 0) {
                    return response_Response.error("Access to this item type is restricted by organizational policy.");
                }
                if (filter != null) {
                    decCipher = decCipher.filter(filter);
                }
                if (decCipher.length === 0) {
                    return response_Response.notFound();
                }
                if (decCipher.length === 1) {
                    decCipher = decCipher[0];
                }
                else {
                    return response_Response.multipleResults(decCipher.map((c) => c.id));
                }
            }
            else {
                const isCipherRestricted = yield this.cliRestrictedItemTypesService.isCipherRestricted(decCipher);
                if (isCipherRestricted) {
                    return response_Response.error("Access to this item type is restricted by organizational policy.");
                }
                // Apply filter if provided to single cipher
                if (filter != null && !filter(decCipher)) {
                    return response_Response.notFound();
                }
            }
            yield this.eventCollectionService.collect(EventType.Cipher_ClientViewed, decCipher.id, true, decCipher.organizationId);
            const res = new CipherResponse(decCipher);
            return response_Response.success(res);
        });
    }
    getUsername(id) {
        return commands_get_command_awaiter(this, void 0, void 0, function* () {
            const cipherResponse = yield this.getCipher(id, (c) => c.type === CipherType.Login && !utils_Utils.isNullOrWhitespace(c.login.username));
            if (!cipherResponse.success) {
                return cipherResponse;
            }
            const cipher = cipherResponse.data;
            if (cipher.type !== CipherType.Login) {
                return response_Response.badRequest("Not a login.");
            }
            if (utils_Utils.isNullOrWhitespace(cipher.login.username)) {
                return response_Response.error("No username available for this login.");
            }
            const res = new StringResponse(cipher.login.username);
            return response_Response.success(res);
        });
    }
    getPassword(id) {
        return commands_get_command_awaiter(this, void 0, void 0, function* () {
            const cipherResponse = yield this.getCipher(id, (c) => c.type === CipherType.Login && !utils_Utils.isNullOrWhitespace(c.login.password));
            if (!cipherResponse.success) {
                return cipherResponse;
            }
            const cipher = cipherResponse.data;
            if (cipher.type !== CipherType.Login) {
                return response_Response.badRequest("Not a login.");
            }
            if (utils_Utils.isNullOrWhitespace(cipher.login.password)) {
                return response_Response.error("No password available for this login.");
            }
            const res = new StringResponse(cipher.login.password);
            return response_Response.success(res);
        });
    }
    getUri(id) {
        return commands_get_command_awaiter(this, void 0, void 0, function* () {
            const cipherResponse = yield this.getCipher(id, (c) => c.type === CipherType.Login &&
                c.login.uris != null &&
                c.login.uris.length > 0 &&
                c.login.uris[0].uri !== "");
            if (!cipherResponse.success) {
                return cipherResponse;
            }
            const cipher = cipherResponse.data;
            if (cipher.type !== CipherType.Login) {
                return response_Response.badRequest("Not a login.");
            }
            if (cipher.login.uris == null ||
                cipher.login.uris.length === 0 ||
                cipher.login.uris[0].uri === "") {
                return response_Response.error("No uri available for this login.");
            }
            const res = new StringResponse(cipher.login.uris[0].uri);
            return response_Response.success(res);
        });
    }
    getTotp(id) {
        return commands_get_command_awaiter(this, void 0, void 0, function* () {
            const cipherResponse = yield this.getCipher(id, (c) => c.type === CipherType.Login && !utils_Utils.isNullOrWhitespace(c.login.totp));
            if (!cipherResponse.success) {
                return cipherResponse;
            }
            const cipher = cipherResponse.data;
            if (cipher.type !== CipherType.Login) {
                return response_Response.badRequest("Not a login.");
            }
            if (utils_Utils.isNullOrWhitespace(cipher.login.totp)) {
                return response_Response.error("No TOTP available for this login.");
            }
            const totpResponse = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.totpService.getCode$(cipher.login.totp));
            if (!totpResponse.code) {
                return response_Response.error("Couldn't generate TOTP code.");
            }
            const account = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$);
            const canAccessPremium = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountProfileService.hasPremiumFromAnySource$(account.id));
            if (!canAccessPremium) {
                const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
                const originalCipher = yield this.cipherService.get(cipher.id, activeUserId);
                if (originalCipher == null ||
                    originalCipher.organizationId == null ||
                    !originalCipher.organizationUseTotp) {
                    return response_Response.error("Premium status is required to use this feature.");
                }
            }
            const res = new StringResponse(totpResponse.code);
            return response_Response.success(res);
        });
    }
    getNotes(id) {
        return commands_get_command_awaiter(this, void 0, void 0, function* () {
            const cipherResponse = yield this.getCipher(id, (c) => !utils_Utils.isNullOrWhitespace(c.notes));
            if (!cipherResponse.success) {
                return cipherResponse;
            }
            const cipher = cipherResponse.data;
            if (utils_Utils.isNullOrWhitespace(cipher.notes)) {
                return response_Response.error("No notes available for this item.");
            }
            const res = new StringResponse(cipher.notes);
            return response_Response.success(res);
        });
    }
    getExposed(id) {
        return commands_get_command_awaiter(this, void 0, void 0, function* () {
            const passwordResponse = yield this.getPassword(id);
            if (!passwordResponse.success) {
                return passwordResponse;
            }
            const exposedNumber = yield this.auditService.passwordLeaked(passwordResponse.data.data);
            const res = new StringResponse(exposedNumber.toString());
            return response_Response.success(res);
        });
    }
    getAttachment(id, options) {
        return commands_get_command_awaiter(this, void 0, void 0, function* () {
            if (options.itemId == null || options.itemId === "") {
                return response_Response.badRequest("--itemid <itemid> required.");
            }
            const itemId = options.itemId.toLowerCase();
            const cipherResponse = yield this.getCipher(itemId);
            if (!cipherResponse.success) {
                return cipherResponse;
            }
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
            const cipher = yield this.getCipherView(itemId, activeUserId);
            if (cipher == null ||
                Array.isArray(cipher) ||
                cipher.attachments == null ||
                cipher.attachments.length === 0) {
                return response_Response.error("No attachments available for this item.");
            }
            let attachments = cipher.attachments.filter((a) => a.id.toLowerCase() === id ||
                (a.fileName != null && a.fileName.toLowerCase().indexOf(id) > -1));
            if (attachments.length === 0) {
                return response_Response.error("Attachment `" + id + "` was not found.");
            }
            const exactMatches = attachments.filter((a) => a.fileName.toLowerCase() === id);
            if (exactMatches.length === 1) {
                attachments = exactMatches;
            }
            if (attachments.length > 1) {
                return response_Response.multipleResults(attachments.map((a) => a.id));
            }
            const canAccessPremium = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountProfileService.hasPremiumFromAnySource$(activeUserId));
            if (!canAccessPremium) {
                const originalCipher = yield this.cipherService.get(cipher.id, activeUserId);
                if (originalCipher == null || originalCipher.organizationId == null) {
                    return response_Response.error("Premium status is required to use this feature.");
                }
            }
            let url;
            try {
                const attachmentDownloadResponse = yield this.apiService.getAttachmentData(cipher.id, attachments[0].id);
                url = attachmentDownloadResponse.url;
            }
            catch (e) {
                if (e instanceof ErrorResponse && e.statusCode === 404) {
                    url = attachments[0].url;
                }
                else if (e instanceof ErrorResponse) {
                    throw new Error(e.getSingleMessage());
                }
                else {
                    throw e;
                }
            }
            const decryptBufferFn = (resp) => this.cipherService.getDecryptedAttachmentBuffer(cipher.id, attachments[0], resp, activeUserId);
            return yield this.saveAttachmentToFile(url, attachments[0].fileName, decryptBufferFn, options.output);
        });
    }
    getFolder(id) {
        return commands_get_command_awaiter(this, void 0, void 0, function* () {
            let decFolder = null;
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
            const userKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.userKey$(activeUserId));
            if (utils_Utils.isGuid(id)) {
                const folder = yield this.folderService.getFromState(id, activeUserId);
                if (folder != null) {
                    decFolder = yield folder.decrypt(userKey);
                }
            }
            else if (id.trim() !== "") {
                let folders = yield this.folderService.getAllDecryptedFromState(activeUserId);
                folders = CliUtils.searchFolders(folders, id);
                if (folders.length > 1) {
                    return response_Response.multipleResults(folders.map((f) => f.id));
                }
                if (folders.length > 0) {
                    decFolder = folders[0];
                }
            }
            if (decFolder == null) {
                return response_Response.notFound();
            }
            const res = new FolderResponse(decFolder);
            return response_Response.success(res);
        });
    }
    getCollection(id) {
        return commands_get_command_awaiter(this, void 0, void 0, function* () {
            let decCollection = null;
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
            if (utils_Utils.isGuid(id)) {
                const collection = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.collectionService.encryptedCollections$(activeUserId).pipe(getById(id)));
                if (collection != null) {
                    const orgKeys = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.orgKeys$(activeUserId).pipe((0,external_rxjs_namespaceObject.filter)((orgKeys) => orgKeys != null)));
                    decCollection = yield collection.decrypt(orgKeys[collection.organizationId], this.encryptService);
                }
            }
            else if (id.trim() !== "") {
                let collections = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.collectionService.decryptedCollections$(activeUserId));
                collections = CliUtils.searchCollections(collections, id);
                if (collections.length > 1) {
                    return response_Response.multipleResults(collections.map((c) => c.id));
                }
                if (collections.length > 0) {
                    decCollection = collections[0];
                }
            }
            if (decCollection == null) {
                return response_Response.notFound();
            }
            const res = new collection_response_CollectionResponse(decCollection);
            return response_Response.success(res);
        });
    }
    getOrganizationCollection(id, options) {
        return commands_get_command_awaiter(this, void 0, void 0, function* () {
            if (options.organizationId == null || options.organizationId === "") {
                return response_Response.badRequest("`organizationid` option is required.");
            }
            if (!utils_Utils.isGuid(id)) {
                return response_Response.badRequest("`" + id + "` is not a GUID.");
            }
            if (!utils_Utils.isGuid(options.organizationId)) {
                return response_Response.badRequest("`" + options.organizationId + "` is not a GUID.");
            }
            try {
                const orgKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId, (0,external_rxjs_namespaceObject.switchMap)((userId) => this.keyService.orgKeys$(userId)), (0,external_rxjs_namespaceObject.map)((orgKeys) => { var _a; return (_a = orgKeys[options.organizationId]) !== null && _a !== void 0 ? _a : null; })));
                if (orgKey == null) {
                    throw new Error("No encryption key for this organization.");
                }
                const response = yield this.apiService.getCollectionAccessDetails(options.organizationId, id);
                const decCollection = yield CollectionView.fromCollectionAccessDetails(response, this.encryptService, orgKey);
                const groups = response.groups == null
                    ? null
                    : response.groups.map((g) => new SelectionReadOnly(g.id, g.readOnly, g.hidePasswords, g.manage));
                const users = response.users == null
                    ? null
                    : response.users.map((g) => new SelectionReadOnly(g.id, g.readOnly, g.hidePasswords, g.manage));
                const res = new OrganizationCollectionResponse(decCollection, groups, users);
                return response_Response.success(res);
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
    getOrganization(id) {
        return commands_get_command_awaiter(this, void 0, void 0, function* () {
            let org = null;
            const userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(account_service_getUserId(this.accountService.activeAccount$));
            if (!userId) {
                return response_Response.badRequest("No user found.");
            }
            if (utils_Utils.isGuid(id)) {
                org = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.organizationService
                    .organizations$(userId)
                    .pipe((0,external_rxjs_namespaceObject.map)((organizations) => organizations.find((o) => o.id === id))));
            }
            else if (id.trim() !== "") {
                let orgs = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.organizationService.organizations$(userId));
                orgs = CliUtils.searchOrganizations(orgs, id);
                if (orgs.length > 1) {
                    return response_Response.multipleResults(orgs.map((c) => c.id));
                }
                if (orgs.length > 0) {
                    org = orgs[0];
                }
            }
            if (org == null) {
                return response_Response.notFound();
            }
            const res = new OrganizationResponse(org);
            return response_Response.success(res);
        });
    }
    getTemplate(id) {
        return commands_get_command_awaiter(this, void 0, void 0, function* () {
            let template = null;
            switch (id.toLowerCase()) {
                case "item":
                    template = CipherExport.template();
                    break;
                case "item.field":
                    template = FieldExport.template();
                    break;
                case "item.login":
                    template = LoginExport.template();
                    break;
                case "item.login.uri":
                    template = LoginUriExport.template();
                    break;
                case "item.card":
                    template = CardExport.template();
                    break;
                case "item.identity":
                    template = IdentityExport.template();
                    break;
                case "item.securenote":
                    template = SecureNoteExport.template();
                    break;
                case "folder":
                    template = FolderExport.template();
                    break;
                case "collection":
                    template = CollectionExport.template();
                    break;
                case "item-collections":
                    template = ["collection-id1", "collection-id2"];
                    break;
                case "org-collection":
                    template = OrganizationCollectionRequest.template();
                    break;
                case "send.file":
                case "send.text":
                    template = response_Response.badRequest(`Invalid template object. Use \`bw send template ${id}\` instead.`);
                    break;
                default:
                    return response_Response.badRequest("Unknown template object.");
            }
            const res = new TemplateResponse(template);
            return response_Response.success(res);
        });
    }
    getFingerprint(id) {
        return commands_get_command_awaiter(this, void 0, void 0, function* () {
            let fingerprint = null;
            if (id === "me") {
                const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
                const publicKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.userPublicKey$(activeUserId));
                if (publicKey == null) {
                    return response_Response.error("No public key available for the active user.");
                }
                fingerprint = yield this.keyService.getFingerprint(activeUserId, publicKey);
            }
            else if (utils_Utils.isGuid(id)) {
                try {
                    const response = yield this.apiService.getUserPublicKey(id);
                    const pubKey = utils_Utils.fromB64ToArray(response.publicKey);
                    fingerprint = yield this.keyService.getFingerprint(id, pubKey);
                }
                catch (_a) {
                    // empty - handled by the null check below
                }
            }
            if (fingerprint == null) {
                return response_Response.notFound();
            }
            const res = new StringResponse(fingerprint.join("-"));
            return response_Response.success(res);
        });
    }
}
class get_command_Options {
    constructor(passedOptions) {
        this.organizationId = (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.organizationid) || (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.organizationId);
        this.itemId = (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.itemid) || (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.itemId);
        this.output = passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.output;
    }
}

;// ./src/admin-console/models/response/organization-user.response.ts
class organization_user_response_OrganizationUserResponse {
    constructor() {
        this.object = "org-member";
    }
}

;// ./src/commands/list.command.ts
var commands_list_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};













class ListCommand {
    constructor(cipherService, folderService, collectionService, organizationService, searchService, organizationUserApiService, apiService, eventCollectionService, accountService, keyService, cliRestrictedItemTypesService, cipherArchiveService) {
        this.cipherService = cipherService;
        this.folderService = folderService;
        this.collectionService = collectionService;
        this.organizationService = organizationService;
        this.searchService = searchService;
        this.organizationUserApiService = organizationUserApiService;
        this.apiService = apiService;
        this.eventCollectionService = eventCollectionService;
        this.accountService = accountService;
        this.keyService = keyService;
        this.cliRestrictedItemTypesService = cliRestrictedItemTypesService;
        this.cipherArchiveService = cipherArchiveService;
    }
    run(object, cmdOptions) {
        return commands_list_command_awaiter(this, void 0, void 0, function* () {
            const normalizedOptions = new commands_list_command_Options(cmdOptions);
            switch (object.toLowerCase()) {
                case "items":
                    return yield this.listCiphers(normalizedOptions);
                case "folders":
                    return yield this.listFolders(normalizedOptions);
                case "collections":
                    return yield this.listCollections(normalizedOptions);
                case "org-collections":
                    return yield this.listOrganizationCollections(normalizedOptions);
                case "org-members":
                    return yield this.listOrganizationMembers(normalizedOptions);
                case "organizations":
                    return yield this.listOrganizations(normalizedOptions);
                default:
                    return response_Response.badRequest("Unknown object.");
            }
        });
    }
    listCiphers(options) {
        return commands_list_command_awaiter(this, void 0, void 0, function* () {
            let ciphers;
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
            const userCanArchive = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.cipherArchiveService.userCanArchive$(activeUserId));
            options.trash = options.trash || false;
            options.archived = userCanArchive && options.archived;
            if (options.url != null && options.url.trim() !== "") {
                ciphers = yield this.cipherService.getAllDecryptedForUrl(options.url, activeUserId);
            }
            else {
                ciphers = yield this.cipherService.getAllDecrypted(activeUserId);
            }
            if (options.folderId != null ||
                options.collectionId != null ||
                options.organizationId != null) {
                ciphers = ciphers.filter((c) => {
                    const matchesStateOptions = this.matchesStateOptions(c, options);
                    if (!matchesStateOptions) {
                        return false;
                    }
                    if (options.folderId != null) {
                        if (options.folderId === "notnull" && c.folderId != null) {
                            return true;
                        }
                        const folderId = options.folderId === "null" ? undefined : options.folderId;
                        if (folderId === c.folderId) {
                            return true;
                        }
                    }
                    if (options.organizationId != null) {
                        if (options.organizationId === "notnull" && c.organizationId != null) {
                            return true;
                        }
                        const organizationId = options.organizationId === "null" ? undefined : options.organizationId;
                        if (organizationId === c.organizationId) {
                            return true;
                        }
                    }
                    if (options.collectionId != null) {
                        if (options.collectionId === "notnull" &&
                            c.collectionIds != null &&
                            c.collectionIds.length > 0) {
                            return true;
                        }
                        const collectionId = options.collectionId === "null" ? null : options.collectionId;
                        if (collectionId == null && (c.collectionIds == null || c.collectionIds.length === 0)) {
                            return true;
                        }
                        if (collectionId != null &&
                            c.collectionIds != null &&
                            c.collectionIds.indexOf(collectionId) > -1) {
                            return true;
                        }
                    }
                    return false;
                });
            }
            else if (options.search == null || options.search.trim() === "") {
                ciphers = ciphers.filter((c) => this.matchesStateOptions(c, options));
            }
            if (options.search != null && options.search.trim() !== "") {
                ciphers = this.searchService.searchCiphersBasic(ciphers, options.search, options.trash, options.archived);
            }
            ciphers = yield this.cliRestrictedItemTypesService.filterRestrictedCiphers(ciphers);
            yield this.eventCollectionService.collectMany(EventType.Cipher_ClientViewed, ciphers, true);
            const res = new list_response_ListResponse(ciphers.map((o) => new CipherResponse(o)));
            return response_Response.success(res);
        });
    }
    listFolders(options) {
        return commands_list_command_awaiter(this, void 0, void 0, function* () {
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
            let folders = yield this.folderService.getAllDecryptedFromState(activeUserId);
            if (options.search != null && options.search.trim() !== "") {
                folders = CliUtils.searchFolders(folders, options.search);
            }
            const res = new list_response_ListResponse(folders.map((o) => new FolderResponse(o)));
            return response_Response.success(res);
        });
    }
    listCollections(options) {
        return commands_list_command_awaiter(this, void 0, void 0, function* () {
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
            let collections = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.collectionService.decryptedCollections$(activeUserId));
            if (options.organizationId != null) {
                collections = collections.filter((c) => {
                    if (options.organizationId === c.organizationId) {
                        return true;
                    }
                    return false;
                });
            }
            if (options.search != null && options.search.trim() !== "") {
                collections = CliUtils.searchCollections(collections, options.search);
            }
            const res = new list_response_ListResponse(collections.map((o) => new collection_response_CollectionResponse(o)));
            return response_Response.success(res);
        });
    }
    listOrganizationCollections(options) {
        return commands_list_command_awaiter(this, void 0, void 0, function* () {
            const userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(account_service_getUserId(this.accountService.activeAccount$));
            if (options.organizationId == null || options.organizationId === "") {
                return response_Response.badRequest("`organizationid` option is required.");
            }
            if (!utils_Utils.isGuid(options.organizationId)) {
                return response_Response.badRequest("`" + options.organizationId + "` is not a GUID.");
            }
            if (!userId) {
                return response_Response.badRequest("No user found.");
            }
            const organization = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.organizationService
                .organizations$(userId)
                .pipe((0,external_rxjs_namespaceObject.map)((organizatons) => organizatons.find((o) => o.id == options.organizationId))));
            if (organization == null) {
                return response_Response.error("Organization not found.");
            }
            try {
                let response;
                if (organization.canViewAllCollections) {
                    response = yield this.apiService.getCollections(options.organizationId);
                }
                else {
                    response = yield this.apiService.getUserCollections();
                }
                const collections = response.data
                    .filter((c) => c.organizationId === options.organizationId)
                    .map((r) => Collection.fromCollectionData(new collection_data_CollectionData(r)));
                const orgKeys = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.orgKeys$(userId));
                if (orgKeys == null) {
                    throw new Error("Organization keys not found.");
                }
                let decCollections = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.collectionService.decryptMany$(collections, orgKeys));
                if (options.search != null && options.search.trim() !== "") {
                    decCollections = CliUtils.searchCollections(decCollections, options.search);
                }
                const res = new list_response_ListResponse(decCollections.map((o) => new collection_response_CollectionResponse(o)));
                return response_Response.success(res);
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
    listOrganizationMembers(options) {
        return commands_list_command_awaiter(this, void 0, void 0, function* () {
            if (options.organizationId == null || options.organizationId === "") {
                return response_Response.badRequest("`organizationid` option is required.");
            }
            if (!utils_Utils.isGuid(options.organizationId)) {
                return response_Response.badRequest("`" + options.organizationId + "` is not a GUID.");
            }
            const userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(account_service_getUserId(this.accountService.activeAccount$));
            if (!userId) {
                return response_Response.badRequest("No user found.");
            }
            const organization = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.organizationService
                .organizations$(userId)
                .pipe((0,external_rxjs_namespaceObject.map)((organizatons) => organizatons.find((o) => o.id == options.organizationId))));
            if (organization == null) {
                return response_Response.error("Organization not found.");
            }
            try {
                const response = yield this.organizationUserApiService.getAllUsers(options.organizationId);
                const res = new list_response_ListResponse(response.data.map((r) => {
                    const u = new organization_user_response_OrganizationUserResponse();
                    u.email = r.email;
                    u.name = r.name;
                    u.id = r.id;
                    u.status = r.status;
                    u.type = r.type;
                    u.twoFactorEnabled = r.twoFactorEnabled;
                    return u;
                }));
                return response_Response.success(res);
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
    listOrganizations(options) {
        return commands_list_command_awaiter(this, void 0, void 0, function* () {
            const userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(account_service_getUserId(this.accountService.activeAccount$));
            if (!userId) {
                return response_Response.badRequest("No user found.");
            }
            let organizations = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.organizationService.memberOrganizations$(userId));
            if (options.search != null && options.search.trim() !== "") {
                organizations = CliUtils.searchOrganizations(organizations, options.search);
            }
            const res = new list_response_ListResponse(organizations.map((o) => new OrganizationResponse(o)));
            return response_Response.success(res);
        });
    }
    /**
     * Checks if the cipher passes the state filter options.
     * @returns true if the cipher matches the requested state
     */
    matchesStateOptions(c, options) {
        const passesTrashFilter = options.trash === c.isDeleted;
        const passesArchivedFilter = options.archived === c.isArchived;
        return passesTrashFilter && passesArchivedFilter;
    }
}
class commands_list_command_Options {
    constructor(passedOptions) {
        this.organizationId = (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.organizationid) || (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.organizationId);
        this.collectionId = (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.collectionid) || (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.collectionId);
        this.folderId = (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.folderid) || (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.folderId);
        this.search = passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.search;
        this.url = passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.url;
        this.trash = CliUtils.convertBooleanOption(passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.trash);
        this.archived = CliUtils.convertBooleanOption(passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.archived);
    }
}

;// ./src/commands/restore.command.ts
var restore_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};



class RestoreCommand {
    constructor(cipherService, accountService, cipherAuthorizationService, cipherArchiveService) {
        this.cipherService = cipherService;
        this.accountService = accountService;
        this.cipherAuthorizationService = cipherAuthorizationService;
        this.cipherArchiveService = cipherArchiveService;
    }
    run(object, id) {
        return restore_command_awaiter(this, void 0, void 0, function* () {
            if (id != null) {
                id = id.toLowerCase();
            }
            switch (object.toLowerCase()) {
                case "item":
                    return yield this.restoreCipher(id);
                default:
                    return response_Response.badRequest("Unknown object.");
            }
        });
    }
    restoreCipher(id) {
        return restore_command_awaiter(this, void 0, void 0, function* () {
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
            const cipher = yield this.cipherService.get(id, activeUserId);
            if (cipher == null) {
                return response_Response.notFound();
            }
            // Determine if restoring from archive or trash
            // When a cipher is archived and deleted, restore from the trash first
            if (cipher.archivedDate && cipher.deletedDate == null) {
                return this.restoreArchivedCipher(cipher, activeUserId);
            }
            else {
                return this.restoreDeletedCipher(cipher, activeUserId);
            }
        });
    }
    /** Restores a cipher from the trash. */
    restoreDeletedCipher(cipher, userId) {
        return restore_command_awaiter(this, void 0, void 0, function* () {
            if (cipher.deletedDate == null) {
                return response_Response.badRequest("Cipher is not in trash.");
            }
            const canRestore = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.cipherAuthorizationService.canRestoreCipher$(cipher));
            if (!canRestore) {
                return response_Response.error("You do not have permission to restore this item");
            }
            try {
                yield this.cipherService.restoreWithServer(cipher.id, userId);
                return response_Response.success();
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
    /** Restore a cipher from the archive vault */
    restoreArchivedCipher(cipher, userId) {
        return restore_command_awaiter(this, void 0, void 0, function* () {
            try {
                yield this.cipherArchiveService.unarchiveWithServer(cipher.id, userId);
                return response_Response.success();
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
}

;// ../../libs/tools/export/vault-export/vault-export-core/src/types/bitwarden-json-export-types.ts
// Unencrypted type guards
function isUnencrypted(data) {
    return data != null && data.encrypted !== true;
}
function isIndividualUnEncrypted(data) {
    return isUnencrypted(data) && data.folders != null;
}
function isOrgUnEncrypted(data) {
    return isUnencrypted(data) && data.collections != null;
}
// Encrypted type guards
function isEncrypted(data) {
    return data != null && data.encrypted === true;
}
function isPasswordProtected(data) {
    return (data != null &&
        data.encrypted === true &&
        data.passwordProtected === true);
}
function isIndividualEncrypted(data) {
    return isEncrypted(data) && data.folders != null;
}
function isOrgEncrypted(data) {
    return isEncrypted(data) && data.collections != null;
}

;// ../../libs/tools/export/vault-export/vault-export-core/src/types/index.ts




;// ../../libs/tools/export/vault-export/vault-export-core/src/services/vault-export.service.abstraction.ts
const EXPORT_FORMATS = ["csv", "json", "encrypted_json", "zip"];
class VaultExportServiceAbstraction {
}

;// ../../libs/tools/export/vault-export/vault-export-core/src/services/vault-export.service.ts
var vault_export_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};



class VaultExportService {
    constructor(individualVaultExportService, organizationVaultExportService, accountService) {
        this.individualVaultExportService = individualVaultExportService;
        this.organizationVaultExportService = organizationVaultExportService;
        this.accountService = accountService;
    }
    /** Creates an export of an individual vault (My vault). Based on the provided format it will either be unencrypted, encrypted or password protected
     * @param userId The userId of the account requesting the export
     * @param format The format of the export
     * @param password An optional password if the export should be password-protected
     * @returns The exported vault
     * @throws Error if the format is csv and a password is provided
     */
    getExport(userId_1) {
        return vault_export_service_awaiter(this, arguments, void 0, function* (userId, format = "csv", password = "") {
            yield this.checkForImpersonation(userId);
            if (!utils_Utils.isNullOrWhitespace(password)) {
                if (format == "csv") {
                    throw new Error("CSV does not support password protected export");
                }
                return this.individualVaultExportService.getPasswordProtectedExport(userId, password);
            }
            return this.individualVaultExportService.getExport(userId, format);
        });
    }
    /** Creates an export of an organizational vault. Based on the provided format it will either be unencrypted, encrypted or password protected
     * @param userId The userId of the account requesting the export
     * @param organizationId The organization id
     * @param format The format of the export
     * @param password The password to protect the export
     * @param onlyManagedCollections If true only managed collections will be exported
     * @returns The exported vault
     * @throws Error if the format is csv and a password is provided
     * @throws Error if the format is zip and the environment does not support exporting attachments
     * @throws Error if the format is not supported
     * @throws Error if the organization id is not a valid guid
     * @throws Error if the organization policies prevent the export
     */
    getOrganizationExport(userId_1, organizationId_1, format_1, password_1) {
        return vault_export_service_awaiter(this, arguments, void 0, function* (userId, organizationId, format, password, onlyManagedCollections = false) {
            yield this.checkForImpersonation(userId);
            if (!utils_Utils.isNullOrWhitespace(password)) {
                if (format == "csv") {
                    throw new Error("CSV does not support password protected export");
                }
                return this.organizationVaultExportService.getPasswordProtectedExport(userId, organizationId, password, onlyManagedCollections);
            }
            return this.organizationVaultExportService.getOrganizationExport(userId, organizationId, format, onlyManagedCollections);
        });
    }
    /**
     * Get available export formats based on vault context
     * @param options Options determining which formats are available
     * @returns Observable stream of available export formats
     */
    formats$(options) {
        const baseFormats = [
            { name: ".json", format: "json" },
            { name: ".csv", format: "csv" },
            { name: ".json (Encrypted)", format: "encrypted_json" },
        ];
        // ZIP format with attachments is only available for individual vault exports
        if (options.isMyVault) {
            return (0,external_rxjs_namespaceObject.of)([...baseFormats, { name: ".zip (with attachments)", format: "zip" }]);
        }
        return (0,external_rxjs_namespaceObject.of)(baseFormats);
    }
    /** Checks if the provided userId matches the currently authenticated user
     * @param userId The userId to check
     * @throws Error if the userId does not match the currently authenticated user
     */
    checkForImpersonation(userId) {
        return vault_export_service_awaiter(this, void 0, void 0, function* () {
            const currentUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
            if (userId !== currentUserId) {
                throw new Error("UserId does not match the currently authenticated user");
            }
        });
    }
}

;// external "papaparse"
const external_papaparse_namespaceObject = require("papaparse");
;// ../../libs/tools/export/vault-export/vault-export-core/src/services/base-vault-export.service.ts
var base_vault_export_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};



class BaseVaultExportService {
    constructor(keyGenerationService, encryptService, cryptoFunctionService, kdfConfigService) {
        this.keyGenerationService = keyGenerationService;
        this.encryptService = encryptService;
        this.cryptoFunctionService = cryptoFunctionService;
        this.kdfConfigService = kdfConfigService;
    }
    buildPasswordExport(userId, clearText, password) {
        return base_vault_export_service_awaiter(this, void 0, void 0, function* () {
            const kdfConfig = yield this.kdfConfigService.getKdfConfig(userId);
            const salt = utils_Utils.fromBufferToB64(yield this.cryptoFunctionService.randomBytes(16));
            const key = yield this.keyGenerationService.deriveVaultExportKey(password, salt, kdfConfig);
            const encKeyValidation = yield this.encryptService.encryptString(utils_Utils.newGuid(), key);
            const encText = yield this.encryptService.encryptString(clearText, key);
            const jsonDoc = {
                encrypted: true,
                passwordProtected: true,
                salt: salt,
                kdfType: kdfConfig.kdfType,
                kdfIterations: kdfConfig.iterations,
                encKeyValidation_DO_NOT_EDIT: encKeyValidation.encryptedString,
                data: encText.encryptedString,
            };
            if (kdfConfig.kdfType === kdf_type_enum_KdfType.Argon2id) {
                jsonDoc.kdfMemory = kdfConfig.memory;
                jsonDoc.kdfParallelism = kdfConfig.parallelism;
            }
            return JSON.stringify(jsonDoc, null, "  ");
        });
    }
    buildCommonCipher(cipher, c) {
        cipher.type = null;
        cipher.name = c.name;
        cipher.notes = c.notes;
        cipher.fields = null;
        cipher.reprompt = c.reprompt;
        cipher.archivedDate = c.archivedDate ? c.archivedDate.toISOString() : null;
        // Login props
        cipher.login_uri = null;
        cipher.login_username = null;
        cipher.login_password = null;
        cipher.login_totp = null;
        if (c.fields) {
            c.fields.forEach((f) => {
                if (!cipher.fields) {
                    cipher.fields = "";
                }
                else {
                    cipher.fields += "\n";
                }
                cipher.fields += (f.name || "") + ": " + f.value;
            });
        }
        switch (c.type) {
            case CipherType.Login:
                cipher.type = "login";
                cipher.login_username = c.login.username;
                cipher.login_password = c.login.password;
                cipher.login_totp = c.login.totp;
                if (c.login.uris) {
                    cipher.login_uri = [];
                    c.login.uris.forEach((u) => {
                        cipher.login_uri.push(u.uri);
                    });
                }
                break;
            case CipherType.SecureNote:
                cipher.type = "note";
                break;
            default:
                return;
        }
        return cipher;
    }
}

;// ../../libs/tools/export/vault-export/vault-export-core/src/services/export-helper.ts
class ExportHelper {
    static getFileName(prefix = "", format = "csv") {
        if (format === "encrypted_json") {
            if (prefix == "") {
                prefix = "encrypted";
            }
            else {
                prefix = "encrypted_" + prefix;
            }
            format = "json";
        }
        const now = new Date();
        const dateString = now.getFullYear() +
            "" +
            this.padNumber(now.getMonth() + 1, 2) +
            "" +
            this.padNumber(now.getDate(), 2) +
            this.padNumber(now.getHours(), 2) +
            "" +
            this.padNumber(now.getMinutes(), 2) +
            this.padNumber(now.getSeconds(), 2);
        return "bitwarden" + (prefix ? "_" + prefix : "") + "_export_" + dateString + "." + format;
    }
    static padNumber(num, width, padCharacter = "0") {
        const numString = num.toString();
        return numString.length >= width
            ? numString
            : new Array(width - numString.length + 1).join(padCharacter) + numString;
    }
}

;// ../../libs/tools/export/vault-export/vault-export-core/src/services/org-vault-export.service.ts
var org_vault_export_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore











class OrganizationVaultExportService extends BaseVaultExportService {
    constructor(cipherService, vaultExportApiService, keyGenerationService, keyService, encryptService, cryptoFunctionService, collectionService, kdfConfigService, restrictedItemTypesService) {
        super(keyGenerationService, encryptService, cryptoFunctionService, kdfConfigService);
        this.cipherService = cipherService;
        this.vaultExportApiService = vaultExportApiService;
        this.keyService = keyService;
        this.collectionService = collectionService;
        this.restrictedItemTypesService = restrictedItemTypesService;
    }
    /** Creates a password protected export of an organizational vault.
     * @param userId The userId of the account requesting the export
     * @param organizationId The organization id
     * @param password The password to protect the export
     * @param onlyManagedCollections If true only managed collections will be exported
     * @returns The exported vault
     */
    getPasswordProtectedExport(userId, organizationId, password, onlyManagedCollections) {
        return org_vault_export_service_awaiter(this, void 0, void 0, function* () {
            const exportVault = yield this.getOrganizationExport(userId, organizationId, "json", onlyManagedCollections);
            return {
                type: "text/plain",
                data: yield this.buildPasswordExport(userId, exportVault.data, password),
                fileName: ExportHelper.getFileName("org", "encrypted_json"),
            };
        });
    }
    /** Creates an export of an organizational vault. Based on the provided format it will either be unencrypted, encrypted
     * @param userId The userId of the account requesting the export
     * @param organizationId The organization id
     * @param format The format of the export
     * @param onlyManagedCollections If true only managed collections will be exported
     * @returns The exported vault
     * @throws Error if the format is zip
     * @throws Error if the organization id is not set
     * @throws Error if the format is not supported
     * @throws Error if the organization policies prevent the export
     */
    getOrganizationExport(userId_1, organizationId_1) {
        return org_vault_export_service_awaiter(this, arguments, void 0, function* (userId, organizationId, format = "csv", onlyManagedCollections) {
            if (utils_Utils.isNullOrWhitespace(organizationId)) {
                throw new Error("OrganizationId must be set");
            }
            if (format === "zip") {
                throw new Error("Zip export not supported for organization");
            }
            if (format === "encrypted_json") {
                return {
                    type: "text/plain",
                    data: onlyManagedCollections
                        ? yield this.getEncryptedManagedExport(userId, organizationId)
                        : yield this.getOrganizationEncryptedExport(userId, organizationId),
                    fileName: ExportHelper.getFileName("org", "encrypted_json"),
                };
            }
            return {
                type: "text/plain",
                data: onlyManagedCollections
                    ? yield this.getDecryptedManagedExport(userId, organizationId, format)
                    : yield this.getOrganizationDecryptedExport(userId, organizationId, format),
                fileName: ExportHelper.getFileName("org", format),
            };
        });
    }
    getOrganizationDecryptedExport(activeUserId, organizationId, format) {
        return org_vault_export_service_awaiter(this, void 0, void 0, function* () {
            const decCollections = [];
            const decCiphers = [];
            const promises = [];
            const orgKeys = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.orgKeys$(activeUserId).pipe((0,external_rxjs_namespaceObject.filter)((orgKeys) => orgKeys != null)));
            const restrictions = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.restrictedItemTypesService.restricted$);
            promises.push(this.vaultExportApiService.getOrganizationExport(organizationId).then((exportData) => {
                const exportPromises = [];
                if (exportData != null) {
                    if (exportData.collections != null && exportData.collections.length > 0) {
                        exportData.collections.forEach((c) => {
                            const collection = Collection.fromCollectionData(new collection_data_CollectionData(c));
                            const orgKey = orgKeys[organizationId];
                            exportPromises.push(collection.decrypt(orgKey, this.encryptService).then((decCol) => {
                                decCollections.push(decCol);
                            }));
                        });
                    }
                    if (exportData.ciphers != null && exportData.ciphers.length > 0) {
                        exportData.ciphers
                            .filter((c) => c.deletedDate === null)
                            .forEach((c) => org_vault_export_service_awaiter(this, void 0, void 0, function* () {
                            const cipher = new Cipher(new CipherData(c));
                            exportPromises.push(this.cipherService.decrypt(cipher, activeUserId).then((decCipher) => {
                                if (!this.restrictedItemTypesService.isCipherRestricted(decCipher, restrictions)) {
                                    decCiphers.push(decCipher);
                                }
                            }));
                        }));
                    }
                }
                return Promise.all(exportPromises);
            }));
            yield Promise.all(promises);
            if (format === "csv") {
                return this.buildCsvExport(decCollections, decCiphers);
            }
            return this.buildJsonExport(decCollections, decCiphers);
        });
    }
    getOrganizationEncryptedExport(userId, organizationId) {
        return org_vault_export_service_awaiter(this, void 0, void 0, function* () {
            const collections = [];
            const ciphers = [];
            const restrictions = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.restrictedItemTypesService.restricted$);
            const exportData = yield this.vaultExportApiService.getOrganizationExport(organizationId);
            if (exportData == null) {
                return;
            }
            if (exportData.collections != null && exportData.collections.length > 0) {
                exportData.collections.forEach((c) => {
                    const collection = Collection.fromCollectionData(new collection_data_CollectionData(c));
                    collections.push(collection);
                });
            }
            if (exportData.ciphers != null && exportData.ciphers.length > 0) {
                exportData.ciphers
                    .filter((c) => c.deletedDate === null)
                    .forEach((c) => {
                    const cipher = new Cipher(new CipherData(c));
                    if (!this.restrictedItemTypesService.isCipherRestricted(cipher, restrictions)) {
                        ciphers.push(cipher);
                    }
                });
            }
            return this.BuildEncryptedExport(userId, organizationId, collections, ciphers);
        });
    }
    getDecryptedManagedExport(activeUserId, organizationId, format) {
        return org_vault_export_service_awaiter(this, void 0, void 0, function* () {
            let decCiphers = [];
            let allDecCiphers = [];
            const promises = [];
            promises.push(this.cipherService.getAllDecrypted(activeUserId).then((ciphers) => {
                allDecCiphers = ciphers;
            }));
            yield Promise.all(promises);
            const decCollections = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.collectionService
                .decryptedCollections$(activeUserId)
                .pipe((0,external_rxjs_namespaceObject.map)((collections) => collections.filter((c) => c.organizationId == organizationId && c.manage))));
            const restrictions = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.restrictedItemTypesService.restricted$);
            decCiphers = allDecCiphers.filter((f) => f.deletedDate == null &&
                f.organizationId == organizationId &&
                decCollections.some((dC) => f.collectionIds.some((cId) => dC.id === cId)) &&
                !this.restrictedItemTypesService.isCipherRestricted(f, restrictions));
            if (format === "csv") {
                return this.buildCsvExport(decCollections, decCiphers);
            }
            return this.buildJsonExport(decCollections, decCiphers);
        });
    }
    getEncryptedManagedExport(activeUserId, organizationId) {
        return org_vault_export_service_awaiter(this, void 0, void 0, function* () {
            let encCiphers = [];
            let allCiphers = [];
            const promises = [];
            promises.push(this.cipherService.getAll(activeUserId).then((ciphers) => {
                allCiphers = ciphers;
            }));
            yield Promise.all(promises);
            const encCollections = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.collectionService.encryptedCollections$(activeUserId).pipe((0,external_rxjs_namespaceObject.map)((collections) => collections !== null && collections !== void 0 ? collections : []), (0,external_rxjs_namespaceObject.map)((collections) => collections.filter((c) => c.organizationId == organizationId && c.manage))));
            const restrictions = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.restrictedItemTypesService.restricted$);
            encCiphers = allCiphers.filter((f) => f.deletedDate == null &&
                f.organizationId == organizationId &&
                encCollections.some((eC) => f.collectionIds.some((cId) => eC.id === cId)) &&
                !this.restrictedItemTypesService.isCipherRestricted(f, restrictions));
            return this.BuildEncryptedExport(activeUserId, organizationId, encCollections, encCiphers);
        });
    }
    BuildEncryptedExport(activeUserId, organizationId, collections, ciphers) {
        return org_vault_export_service_awaiter(this, void 0, void 0, function* () {
            const orgKeys = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.orgKeys$(activeUserId));
            const keyForEncryption = orgKeys === null || orgKeys === void 0 ? void 0 : orgKeys[organizationId];
            if (keyForEncryption == null) {
                throw new Error("No encryption key found for organization");
            }
            const encKeyValidation = yield this.encryptService.encryptString(newGuid(), keyForEncryption);
            const jsonDoc = {
                encrypted: true,
                encKeyValidation_DO_NOT_EDIT: encKeyValidation.encryptedString,
                collections: [],
                items: [],
            };
            collections.forEach((c) => {
                const collection = new CollectionWithIdExport();
                collection.build(c);
                jsonDoc.collections.push(collection);
            });
            ciphers.forEach((c) => {
                const cipher = new CipherWithIdExport();
                cipher.build(c);
                jsonDoc.items.push(cipher);
            });
            return JSON.stringify(jsonDoc, null, "  ");
        });
    }
    buildCsvExport(decCollections, decCiphers) {
        const collectionsMap = new Map();
        decCollections.forEach((c) => {
            collectionsMap.set(c.id, c);
        });
        const exportCiphers = [];
        decCiphers.forEach((c) => {
            // only export logins and secure notes
            if (c.type !== CipherType.Login && c.type !== CipherType.SecureNote) {
                return;
            }
            const cipher = {};
            cipher.collections = [];
            if (c.collectionIds != null) {
                cipher.collections = c.collectionIds
                    .filter((id) => collectionsMap.has(id))
                    .map((id) => collectionsMap.get(id).name);
            }
            this.buildCommonCipher(cipher, c);
            exportCiphers.push(cipher);
        });
        return external_papaparse_namespaceObject.unparse(exportCiphers);
    }
    buildJsonExport(decCollections, decCiphers) {
        const jsonDoc = {
            encrypted: false,
            collections: [],
            items: [],
        };
        decCollections.forEach((c) => {
            const collection = new CollectionWithIdExport();
            collection.build(c);
            jsonDoc.collections.push(collection);
        });
        decCiphers.forEach((c) => {
            const cipher = new CipherWithIdExport();
            cipher.build(c);
            delete cipher.key;
            jsonDoc.items.push(cipher);
        });
        return JSON.stringify(jsonDoc, null, "  ");
    }
}

;// ../../libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.ts
var individual_vault_export_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore








class IndividualVaultExportService extends BaseVaultExportService {
    constructor(folderService, cipherService, keyGenerationService, keyService, encryptService, cryptoFunctionService, kdfConfigService, apiService, restrictedItemTypesService) {
        super(keyGenerationService, encryptService, cryptoFunctionService, kdfConfigService);
        this.folderService = folderService;
        this.cipherService = cipherService;
        this.keyService = keyService;
        this.apiService = apiService;
        this.restrictedItemTypesService = restrictedItemTypesService;
    }
    /** Creates an export of an individual vault (My Vault). Based on the provided format it will either be unencrypted, encrypted or password protected and in case zip is selected will include attachments
     * @param userId The userId of the account requesting the export
     * @param format The format of the export
     */
    getExport(userId_1) {
        return individual_vault_export_service_awaiter(this, arguments, void 0, function* (userId, format = "csv") {
            if (format === "encrypted_json") {
                return this.getEncryptedExport(userId);
            }
            else if (format === "zip") {
                return this.getDecryptedExportZip(userId);
            }
            return this.getDecryptedExport(userId, format);
        });
    }
    /** Creates a password protected export of an individual vault (My Vault) as a JSON file
     * @param userId The userId of the account requesting the export
     * @param password The password to encrypt the export with
     * @returns A password-protected encrypted individual vault export
     */
    getPasswordProtectedExport(userId, password) {
        return individual_vault_export_service_awaiter(this, void 0, void 0, function* () {
            const exportVault = yield this.getExport(userId, "json");
            if (exportVault.type !== "text/plain") {
                throw new Error("Unexpected export type");
            }
            return {
                type: "text/plain",
                data: yield this.buildPasswordExport(userId, exportVault.data, password),
                fileName: ExportHelper.getFileName("", "encrypted_json"),
            };
        });
    }
    /** Creates a unencrypted export of an individual vault including attachments
     * @param activeUserId The user ID of the user requesting the export
     * @returns A unencrypted export including attachments
     */
    getDecryptedExportZip(activeUserId) {
        return individual_vault_export_service_awaiter(this, void 0, void 0, function* () {
            const zip = new external_jszip_namespaceObject();
            // ciphers
            const exportedVault = yield this.getDecryptedExport(activeUserId, "json");
            zip.file("data.json", exportedVault.data);
            const attachmentsFolder = zip.folder("attachments");
            if (attachmentsFolder == null) {
                throw new Error("Error creating attachments folder");
            }
            // attachments
            for (const cipher of yield this.cipherService.getAllDecrypted(activeUserId)) {
                if (!cipher.attachments ||
                    cipher.attachments.length === 0 ||
                    cipher.deletedDate != null ||
                    cipher.organizationId != null) {
                    continue;
                }
                const cipherFolder = attachmentsFolder.folder(cipher.id);
                for (const attachment of cipher.attachments) {
                    const response = yield this.downloadAttachment(cipher.id, attachment.id);
                    try {
                        const decBuf = yield this.cipherService.getDecryptedAttachmentBuffer(cipher.id, attachment, response, activeUserId);
                        cipherFolder.file(attachment.fileName, decBuf);
                    }
                    catch (_a) {
                        throw new Error("Error decrypting attachment");
                    }
                }
            }
            const blobData = yield zip.generateAsync({ type: "blob" });
            return {
                type: "application/zip",
                data: blobData,
                fileName: ExportHelper.getFileName("", "zip"),
            };
        });
    }
    downloadAttachment(cipherId, attachmentId) {
        return individual_vault_export_service_awaiter(this, void 0, void 0, function* () {
            const attachmentDownloadResponse = yield this.apiService.getAttachmentData(cipherId, attachmentId);
            const url = attachmentDownloadResponse.url;
            const response = yield fetch(new Request(url, { cache: "no-store" }));
            if (response.status !== 200) {
                throw new Error("Error downloading attachment");
            }
            return response;
        });
    }
    getDecryptedExport(activeUserId, format) {
        return individual_vault_export_service_awaiter(this, void 0, void 0, function* () {
            let decFolders = [];
            let decCiphers = [];
            const promises = [];
            promises.push((0,external_rxjs_namespaceObject.firstValueFrom)(this.folderService.folderViews$(activeUserId)).then((folders) => {
                decFolders = folders;
            }));
            const restrictions = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.restrictedItemTypesService.restricted$);
            promises.push(this.cipherService.getAllDecrypted(activeUserId).then((ciphers) => {
                decCiphers = ciphers.filter((f) => f.deletedDate == null &&
                    !this.restrictedItemTypesService.isCipherRestricted(f, restrictions));
            }));
            yield Promise.all(promises);
            if (format === "csv") {
                return {
                    type: "text/plain",
                    data: this.buildCsvExport(decFolders, decCiphers),
                    fileName: ExportHelper.getFileName("", "csv"),
                };
            }
            return {
                type: "text/plain",
                data: this.buildJsonExport(decFolders, decCiphers),
                fileName: ExportHelper.getFileName("", "json"),
            };
        });
    }
    getEncryptedExport(activeUserId) {
        return individual_vault_export_service_awaiter(this, void 0, void 0, function* () {
            if (!activeUserId) {
                throw new Error("User ID must not be null or undefined");
            }
            let folders = [];
            let ciphers = [];
            const promises = [];
            promises.push((0,external_rxjs_namespaceObject.firstValueFrom)(this.folderService.folders$(activeUserId)).then((f) => {
                folders = f;
            }));
            const restrictions = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.restrictedItemTypesService.restricted$);
            promises.push(this.cipherService.getAll(activeUserId).then((c) => {
                ciphers = c.filter((f) => f.deletedDate == null &&
                    !this.restrictedItemTypesService.isCipherRestricted(f, restrictions));
            }));
            yield Promise.all(promises);
            const userKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.userKey$(activeUserId));
            const encKeyValidation = yield this.encryptService.encryptString(utils_Utils.newGuid(), userKey);
            const jsonDoc = {
                encrypted: true,
                encKeyValidation_DO_NOT_EDIT: encKeyValidation.encryptedString,
                folders: [],
                items: [],
            };
            folders.forEach((f) => {
                if (!f.id) {
                    return;
                }
                const folder = new FolderWithIdExport();
                folder.build(f);
                jsonDoc.folders.push(folder);
            });
            ciphers.forEach((c) => {
                if (c.organizationId != null) {
                    return;
                }
                const cipher = new CipherWithIdExport();
                cipher.build(c);
                cipher.collectionIds = null;
                jsonDoc.items.push(cipher);
            });
            return {
                type: "text/plain",
                data: JSON.stringify(jsonDoc, null, "  "),
                fileName: ExportHelper.getFileName("", "encrypted_json"),
            };
        });
    }
    buildCsvExport(decFolders, decCiphers) {
        const foldersMap = new Map();
        decFolders.forEach((f) => {
            if (f.id) {
                foldersMap.set(f.id, f);
            }
        });
        const exportCiphers = [];
        decCiphers.forEach((c) => {
            // only export logins and secure notes
            if (c.type !== CipherType.Login && c.type !== CipherType.SecureNote) {
                return;
            }
            if (c.organizationId != null) {
                return;
            }
            const cipher = {};
            cipher.folder =
                c.folderId != null && foldersMap.has(c.folderId) ? foldersMap.get(c.folderId).name : null;
            cipher.favorite = c.favorite ? 1 : null;
            this.buildCommonCipher(cipher, c);
            exportCiphers.push(cipher);
        });
        return external_papaparse_namespaceObject.unparse(exportCiphers);
    }
    buildJsonExport(decFolders, decCiphers) {
        const jsonDoc = {
            encrypted: false,
            folders: [],
            items: [],
        };
        decFolders.forEach((f) => {
            if (!f.id) {
                return;
            }
            const folder = new FolderWithIdExport();
            folder.build(f);
            jsonDoc.folders.push(folder);
        });
        decCiphers.forEach((c) => {
            if (c.organizationId != null) {
                return;
            }
            const cipher = new CipherWithIdExport();
            cipher.build(c);
            cipher.collectionIds = null;
            delete cipher.key;
            jsonDoc.items.push(cipher);
        });
        return JSON.stringify(jsonDoc, null, "  ");
    }
}

;// ../../libs/common/src/vault/models/api/card.api.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

class CardApi extends BaseResponse {
    constructor(data = null) {
        super(data);
        if (data == null) {
            return;
        }
        this.cardholderName = this.getResponseProperty("CardholderName");
        this.brand = this.getResponseProperty("Brand");
        this.number = this.getResponseProperty("Number");
        this.expMonth = this.getResponseProperty("ExpMonth");
        this.expYear = this.getResponseProperty("ExpYear");
        this.code = this.getResponseProperty("Code");
    }
}

;// ../../libs/common/src/vault/models/api/field.api.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

class FieldApi extends BaseResponse {
    constructor(data = null) {
        super(data);
        if (data == null) {
            return;
        }
        this.type = this.getResponseProperty("Type");
        this.name = this.getResponseProperty("Name");
        this.value = this.getResponseProperty("Value");
        this.linkedId = this.getResponseProperty("linkedId");
    }
}

;// ../../libs/common/src/vault/models/api/identity.api.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

class IdentityApi extends BaseResponse {
    constructor(data = null) {
        super(data);
        if (data == null) {
            return;
        }
        this.title = this.getResponseProperty("Title");
        this.firstName = this.getResponseProperty("FirstName");
        this.middleName = this.getResponseProperty("MiddleName");
        this.lastName = this.getResponseProperty("LastName");
        this.address1 = this.getResponseProperty("Address1");
        this.address2 = this.getResponseProperty("Address2");
        this.address3 = this.getResponseProperty("Address3");
        this.city = this.getResponseProperty("City");
        this.state = this.getResponseProperty("State");
        this.postalCode = this.getResponseProperty("PostalCode");
        this.country = this.getResponseProperty("Country");
        this.company = this.getResponseProperty("Company");
        this.email = this.getResponseProperty("Email");
        this.phone = this.getResponseProperty("Phone");
        this.ssn = this.getResponseProperty("SSN");
        this.username = this.getResponseProperty("Username");
        this.passportNumber = this.getResponseProperty("PassportNumber");
        this.licenseNumber = this.getResponseProperty("LicenseNumber");
    }
}

;// ../../libs/common/src/vault/models/api/fido2-credential.api.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

class Fido2CredentialApi extends BaseResponse {
    constructor(data = null) {
        super(data);
        if (data == null) {
            return;
        }
        this.credentialId = this.getResponseProperty("CredentialId");
        this.keyType = this.getResponseProperty("KeyType");
        this.keyAlgorithm = this.getResponseProperty("KeyAlgorithm");
        this.keyCurve = this.getResponseProperty("KeyCurve");
        this.keyValue = this.getResponseProperty("keyValue");
        this.rpId = this.getResponseProperty("RpId");
        this.userHandle = this.getResponseProperty("UserHandle");
        this.userName = this.getResponseProperty("UserName");
        this.counter = this.getResponseProperty("Counter");
        this.rpName = this.getResponseProperty("RpName");
        this.userDisplayName = this.getResponseProperty("UserDisplayName");
        this.discoverable = this.getResponseProperty("Discoverable");
        this.creationDate = this.getResponseProperty("CreationDate");
    }
}

;// ../../libs/common/src/vault/models/api/login-uri.api.ts

class LoginUriApi extends BaseResponse {
    constructor(data = null) {
        super(data);
        this.match = null;
        if (data == null) {
            return;
        }
        this.uri = this.getResponseProperty("Uri");
        this.uriChecksum = this.getResponseProperty("UriChecksum");
        const match = this.getResponseProperty("Match");
        this.match = match != null ? match : null;
    }
}

;// ../../libs/common/src/vault/models/api/login.api.ts



class LoginApi extends BaseResponse {
    constructor(data = null) {
        super(data);
        if (data == null) {
            return;
        }
        this.username = this.getResponseProperty("Username");
        this.password = this.getResponseProperty("Password");
        this.passwordRevisionDate = this.getResponseProperty("PasswordRevisionDate");
        this.totp = this.getResponseProperty("Totp");
        this.autofillOnPageLoad = this.getResponseProperty("AutofillOnPageLoad");
        const uris = this.getResponseProperty("Uris");
        if (uris != null) {
            this.uris = uris.map((u) => new LoginUriApi(u));
        }
        const fido2Credentials = this.getResponseProperty("Fido2Credentials");
        if (fido2Credentials != null) {
            this.fido2Credentials = fido2Credentials.map((key) => new Fido2CredentialApi(key));
        }
    }
}

;// ../../libs/common/src/vault/models/api/secure-note.api.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

class SecureNoteApi extends BaseResponse {
    constructor(data = null) {
        super(data);
        if (data == null) {
            return;
        }
        this.type = this.getResponseProperty("Type");
    }
}

;// ../../libs/common/src/vault/models/api/ssh-key.api.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

class SshKeyApi extends BaseResponse {
    constructor(data = null) {
        super(data);
        if (data == null) {
            return;
        }
        this.privateKey = this.getResponseProperty("PrivateKey");
        this.publicKey = this.getResponseProperty("PublicKey");
        this.keyFingerprint = this.getResponseProperty("KeyFingerprint");
    }
}

;// ../../libs/common/src/vault/models/response/attachment.response.ts

class attachment_response_AttachmentResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.id = this.getResponseProperty("Id");
        this.url = this.getResponseProperty("Url");
        this.fileName = this.getResponseProperty("FileName");
        this.key = this.getResponseProperty("Key");
        this.size = this.getResponseProperty("Size");
        this.sizeName = this.getResponseProperty("SizeName");
    }
}

;// ../../libs/common/src/vault/models/response/password-history.response.ts

class password_history_response_PasswordHistoryResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.password = this.getResponseProperty("Password");
        this.lastUsedDate = this.getResponseProperty("LastUsedDate");
    }
}

;// ../../libs/common/src/vault/models/response/cipher.response.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore











class cipher_response_CipherResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.id = this.getResponseProperty("Id");
        this.organizationId = this.getResponseProperty("OrganizationId");
        this.folderId = this.getResponseProperty("FolderId") || null;
        this.type = this.getResponseProperty("Type");
        this.name = this.getResponseProperty("Name");
        this.notes = this.getResponseProperty("Notes");
        this.favorite = this.getResponseProperty("Favorite") || false;
        this.edit = !!this.getResponseProperty("Edit");
        if (this.getResponseProperty("ViewPassword") == null) {
            this.viewPassword = true;
        }
        else {
            this.viewPassword = this.getResponseProperty("ViewPassword");
        }
        this.permissions = new CipherPermissionsApi(this.getResponseProperty("Permissions"));
        this.organizationUseTotp = this.getResponseProperty("OrganizationUseTotp");
        this.revisionDate = this.getResponseProperty("RevisionDate");
        this.collectionIds = this.getResponseProperty("CollectionIds");
        this.creationDate = this.getResponseProperty("CreationDate");
        this.deletedDate = this.getResponseProperty("DeletedDate");
        this.archivedDate = this.getResponseProperty("ArchivedDate");
        const login = this.getResponseProperty("Login");
        if (login != null) {
            this.login = new LoginApi(login);
        }
        const card = this.getResponseProperty("Card");
        if (card != null) {
            this.card = new CardApi(card);
        }
        const identity = this.getResponseProperty("Identity");
        if (identity != null) {
            this.identity = new IdentityApi(identity);
        }
        const secureNote = this.getResponseProperty("SecureNote");
        if (secureNote != null) {
            this.secureNote = new SecureNoteApi(secureNote);
        }
        const sshKey = this.getResponseProperty("sshKey");
        if (sshKey != null) {
            this.sshKey = new SshKeyApi(sshKey);
        }
        const fields = this.getResponseProperty("Fields");
        if (fields != null) {
            this.fields = fields.map((f) => new FieldApi(f));
        }
        const attachments = this.getResponseProperty("Attachments");
        if (attachments != null) {
            this.attachments = attachments.map((a) => new attachment_response_AttachmentResponse(a));
        }
        const passwordHistory = this.getResponseProperty("PasswordHistory");
        if (passwordHistory != null) {
            this.passwordHistory = passwordHistory.map((h) => new password_history_response_PasswordHistoryResponse(h));
        }
        this.reprompt = this.getResponseProperty("Reprompt") || CipherRepromptType.None;
        this.key = this.getResponseProperty("Key") || null;
    }
}

;// ../../libs/common/src/admin-console/models/response/organization-export.response.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore



class OrganizationExportResponse extends BaseResponse {
    constructor(response) {
        super(response);
        const collections = this.getResponseProperty("Collections");
        if (collections != null) {
            this.collections = collections.map((c) => new CollectionResponse(c));
        }
        const ciphers = this.getResponseProperty("Ciphers");
        if (ciphers != null) {
            this.ciphers = ciphers.map((c) => new cipher_response_CipherResponse(c));
        }
    }
}

;// ../../libs/tools/export/vault-export/vault-export-core/src/services/api/default-vault-export-api.service.ts
var default_vault_export_api_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

/**
 * Service for handling vault export API interactions.
 * @param apiService - An instance of {@link ApiService} used to make HTTP requests.
 */
class DefaultVaultExportApiService {
    constructor(apiService) {
        this.apiService = apiService;
    }
    getOrganizationExport(organizationId) {
        return default_vault_export_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("GET", "/organizations/" + organizationId + "/export", undefined, true, true);
            return new OrganizationExportResponse(r);
        });
    }
}

;// ../../libs/tools/export/vault-export/vault-export-core/src/services/api/index.ts



;// ../../libs/tools/export/vault-export/vault-export-core/src/index.ts










;// ./src/tools/export.command.ts
var export_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};









class ExportCommand {
    constructor(exportService, policyService, eventCollectionService, accountService) {
        this.exportService = exportService;
        this.policyService = policyService;
        this.eventCollectionService = eventCollectionService;
        this.accountService = accountService;
    }
    run(options) {
        return export_command_awaiter(this, void 0, void 0, function* () {
            var _a;
            const policyApplies$ = this.accountService.activeAccount$.pipe(account_service_getUserId, (0,external_rxjs_namespaceObject.switchMap)((userId) => this.policyService.policyAppliesToUser$(policy_type_enum_PolicyType.DisablePersonalVaultExport, userId)));
            if (options.organizationid == null && (yield (0,external_rxjs_namespaceObject.firstValueFrom)(policyApplies$))) {
                return response_Response.badRequest("One or more organization policies prevents you from exporting your personal vault.");
            }
            let password = options.password;
            // has password and format is 'json' => should have the same behaviour as 'encrypted_json'
            // format is 'undefined' => Defaults to 'csv'
            // Any other case => returns the options.format
            const format = password && options.format == "json" ? "encrypted_json" : ((_a = options.format) !== null && _a !== void 0 ? _a : "csv");
            if (!this.isSupportedExportFormat(format)) {
                return response_Response.badRequest(`'${format}' is not a supported export format. Supported formats: ${EXPORT_FORMATS.join(", ")}.`);
            }
            if (options.organizationid != null && !utils_Utils.isGuid(options.organizationid)) {
                return response_Response.error("`" + options.organizationid + "` is not a GUID.");
            }
            let exportContent = null;
            try {
                if (format === "encrypted_json") {
                    password = yield this.promptPassword(password);
                }
                const userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
                exportContent =
                    options.organizationid == null
                        ? yield this.exportService.getExport(userId, format, password)
                        : yield this.exportService.getOrganizationExport(userId, options.organizationid, format, password);
                const eventType = options.organizationid
                    ? EventType.Organization_ClientExportedVault
                    : EventType.User_ClientExportedVault;
                // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
                // eslint-disable-next-line @typescript-eslint/no-floating-promises
                this.eventCollectionService.collect(eventType, null, true, options.organizationid);
            }
            catch (e) {
                return response_Response.error(e);
            }
            return yield this.saveFile(exportContent, options);
        });
    }
    saveFile(exportContent, options) {
        return export_command_awaiter(this, void 0, void 0, function* () {
            try {
                if (exportContent.type === "application/zip") {
                    exportContent = exportContent;
                    const arrayBuffer = yield exportContent.data.arrayBuffer();
                    const buffer = Buffer.from(arrayBuffer);
                    return yield CliUtils.saveResultToFile(buffer, options.output, exportContent.fileName);
                }
                return yield CliUtils.saveResultToFile(exportContent.data, options.output, exportContent.fileName);
            }
            catch (e) {
                return response_Response.error(e.toString());
            }
        });
    }
    promptPassword(password) {
        return export_command_awaiter(this, void 0, void 0, function* () {
            // boolean => flag set with no value, we need to prompt for password
            // string => flag set with value, use this value for password
            // undefined/null/false => account protect, not password, no password needed
            if (typeof password === "string") {
                return password;
            }
            else if (password) {
                const answer = yield external_inquirer_namespaceObject.createPromptModule({
                    output: process.stderr,
                })({
                    type: "password",
                    name: "password",
                    message: "Export file password:",
                });
                return answer.password;
            }
            return null;
        });
    }
    isSupportedExportFormat(format) {
        return EXPORT_FORMATS.includes(format);
    }
}

;// ./src/tools/import.command.ts
var import_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};







class ImportCommand {
    constructor(importService, organizationService, syncService, accountService) {
        this.importService = importService;
        this.organizationService = organizationService;
        this.syncService = syncService;
        this.accountService = accountService;
    }
    run(format, filepath, options) {
        return import_command_awaiter(this, void 0, void 0, function* () {
            const organizationId = options.organizationid;
            if (organizationId != null) {
                const userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(account_service_getUserId(this.accountService.activeAccount$));
                if (!userId) {
                    return response_Response.badRequest("No user found.");
                }
                const organization = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.organizationService.organizations$(userId).pipe(organization_service_abstraction_getOrganizationById(organizationId)));
                if (organization == null) {
                    return response_Response.badRequest(`You do not belong to an organization with the ID of ${organizationId}. Check the organization ID and sync your vault.`);
                }
                if (!organization.canAccessImport) {
                    return response_Response.badRequest("You are not authorized to import into the provided organization.");
                }
            }
            if (options.formats || false) {
                return yield this.list();
            }
            else {
                return yield this.import(format, filepath, organizationId);
            }
        });
    }
    import(format, filepath, organizationId) {
        return import_command_awaiter(this, void 0, void 0, function* () {
            if (format == null) {
                return response_Response.badRequest("`format` was not provided.");
            }
            if (filepath == null || filepath === "") {
                return response_Response.badRequest("`filepath` was not provided.");
            }
            const promptForPassword_callback = () => import_command_awaiter(this, void 0, void 0, function* () {
                return yield this.promptPassword();
            });
            const importer = yield this.importService.getImporter(format, promptForPassword_callback, organizationId);
            if (importer === null) {
                return response_Response.badRequest("Proper importer type required.");
            }
            try {
                let contents;
                if (format === "1password1pux" && filepath.endsWith(".1pux")) {
                    contents = yield CliUtils.extractZipContent(filepath, "export.data");
                }
                else if (format === "protonpass" && filepath.endsWith(".zip")) {
                    contents = yield CliUtils.extractZipContent(filepath, "Proton Pass/data.json");
                }
                else {
                    contents = yield CliUtils.readFile(filepath);
                }
                if (contents === null || contents === "") {
                    return response_Response.badRequest("Import file was empty.");
                }
                const response = yield this.importService.import(importer, contents, organizationId);
                if (response.success) {
                    // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
                    // eslint-disable-next-line @typescript-eslint/no-floating-promises
                    this.syncService.fullSync(true);
                    return response_Response.success(new MessageResponse("Imported " + filepath, null));
                }
            }
            catch (err) {
                if (err.message) {
                    return response_Response.badRequest(err.message);
                }
                return response_Response.badRequest(err);
            }
        });
    }
    list() {
        return import_command_awaiter(this, void 0, void 0, function* () {
            const options = this.importService
                .getImportOptions()
                .sort((a, b) => {
                return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
            })
                .map((option) => option.id)
                .join("\n");
            const res = new MessageResponse("Supported input formats:", options);
            res.raw = options;
            return response_Response.success(res);
        });
    }
    promptPassword() {
        return import_command_awaiter(this, void 0, void 0, function* () {
            const answer = yield external_inquirer_namespaceObject.createPromptModule({
                output: process.stderr,
            })({
                type: "password",
                name: "password",
                message: "Import file password:",
            });
            return answer.password;
        });
    }
}

;// ../../libs/common/src/vault/utils/cipher-view-like-utils.ts
var cipher_view_like_utils_a;




/**
 * Utility class for working with ciphers that can be either a {@link CipherView} or a {@link CipherListView}.
 */
class CipherViewLikeUtils {
}
cipher_view_like_utils_a = CipherViewLikeUtils;
/** @returns true when the given cipher is an instance of {@link CipherListView}. */
CipherViewLikeUtils.isCipherListView = (cipher) => {
    return typeof cipher.type === "object" || typeof cipher.type === "string";
};
/** @returns The login object from the input cipher. If the cipher is not of type Login, returns null. */
CipherViewLikeUtils.getLogin = (cipher) => {
    if (cipher_view_like_utils_a.isCipherListView(cipher)) {
        if (typeof cipher.type !== "object") {
            return null;
        }
        return "login" in cipher.type ? cipher.type.login : null;
    }
    return cipher.type === CipherType.Login ? cipher.login : null;
};
/** @returns The first URI for a login cipher. If the cipher is not of type Login or has no associated URIs, returns null. */
CipherViewLikeUtils.uri = (cipher) => {
    var _b;
    const login = cipher_view_like_utils_a.getLogin(cipher);
    if (!login) {
        return null;
    }
    if ("uri" in login) {
        return login.uri;
    }
    return ((_b = login.uris) === null || _b === void 0 ? void 0 : _b.length) ? login.uris[0].uri : null;
};
/** @returns The login object from the input cipher. If the cipher is not of type Login, returns null. */
CipherViewLikeUtils.getCard = (cipher) => {
    if (cipher_view_like_utils_a.isCipherListView(cipher)) {
        if (typeof cipher.type !== "object") {
            return null;
        }
        return "card" in cipher.type ? cipher.type.card : null;
    }
    return cipher.type === CipherType.Card ? cipher.card : null;
};
/**  @returns `true` when the cipher has been archived, `false` otherwise. */
CipherViewLikeUtils.isArchived = (cipher) => {
    if (cipher_view_like_utils_a.isCipherListView(cipher)) {
        return !!cipher.archivedDate;
    }
    return cipher.isArchived;
};
/**  @returns `true` when the cipher has been deleted, `false` otherwise. */
CipherViewLikeUtils.isDeleted = (cipher) => {
    if (cipher_view_like_utils_a.isCipherListView(cipher)) {
        return !!cipher.deletedDate;
    }
    return cipher.isDeleted;
};
/**  @returns `true` when the cipher is not assigned to a collection, `false` otherwise. */
CipherViewLikeUtils.isUnassigned = (cipher) => {
    if (cipher_view_like_utils_a.isCipherListView(cipher)) {
        return (cipher.organizationId != null &&
            (cipher.collectionIds == null || cipher.collectionIds.length === 0));
    }
    return cipher.isUnassigned;
};
/** @returns `true` when the user can assign the cipher to a collection, `false` otherwise. */
CipherViewLikeUtils.canAssignToCollections = (cipher) => {
    if (cipher_view_like_utils_a.isCipherListView(cipher)) {
        if (!cipher.organizationId) {
            return true;
        }
        return cipher.edit && cipher.viewPassword;
    }
    return cipher.canAssignToCollections;
};
/**
 * Returns the type of the cipher.
 * For consistency, when the given cipher is a {@link CipherListView} the {@link CipherType} equivalent will be returned.
 */
CipherViewLikeUtils.getType = (cipher) => {
    if (!cipher_view_like_utils_a.isCipherListView(cipher)) {
        return cipher.type;
    }
    // CipherListViewType is a string, so we need to map it to CipherType.
    switch (true) {
        case cipher.type === "secureNote":
            return CipherType.SecureNote;
        case cipher.type === "sshKey":
            return CipherType.SshKey;
        case cipher.type === "identity":
            return CipherType.Identity;
        case typeof cipher.type === "object" && "card" in cipher.type:
            return CipherType.Card;
        case typeof cipher.type === "object" && "login" in cipher.type:
            return CipherType.Login;
        default:
            throw new Error(`Unknown cipher type: ${cipher.type}`);
    }
};
/** @returns The subtitle of the cipher. */
CipherViewLikeUtils.subtitle = (cipher) => {
    if (!cipher_view_like_utils_a.isCipherListView(cipher)) {
        return cipher.subTitle;
    }
    return cipher.subtitle;
};
/** @returns `true` when the cipher has attachments, false otherwise. */
CipherViewLikeUtils.hasAttachments = (cipher) => {
    if (cipher_view_like_utils_a.isCipherListView(cipher)) {
        return typeof cipher.attachments === "number" && cipher.attachments > 0;
    }
    return cipher.hasAttachments;
};
/**
 * @returns `true` when one of the URIs for the cipher can be launched.
 * When a non-login cipher is passed, it will return false.
 */
CipherViewLikeUtils.canLaunch = (cipher) => {
    var _b;
    const login = cipher_view_like_utils_a.getLogin(cipher);
    if (!login) {
        return false;
    }
    return !!((_b = login.uris) === null || _b === void 0 ? void 0 : _b.map((u) => toLoginUriView(u)).some((uri) => uri.canLaunch));
};
/**
 * @returns The first launch-able URI for the cipher.
 * When a non-login cipher is passed or none of the URLs, it will return undefined.
 */
CipherViewLikeUtils.getLaunchUri = (cipher) => {
    var _b, _c;
    const login = cipher_view_like_utils_a.getLogin(cipher);
    if (!login) {
        return undefined;
    }
    return (_c = (_b = login.uris) === null || _b === void 0 ? void 0 : _b.map((u) => toLoginUriView(u)).find((uri) => uri.canLaunch)) === null || _c === void 0 ? void 0 : _c.launchUri;
};
/**
 * @returns `true` when the `targetUri` matches for any URI on the cipher.
 * Uses the existing logic from `LoginView.matchesUri` for both `CipherView` and `CipherListView`
 */
CipherViewLikeUtils.matchesUri = (cipher, targetUri, equivalentDomains, defaultUriMatch = domain_service_UriMatchStrategy.Domain, overrideNeverMatchStrategy) => {
    var _b;
    if (cipher_view_like_utils_a.getType(cipher) !== CipherType.Login) {
        return false;
    }
    if (!cipher_view_like_utils_a.isCipherListView(cipher)) {
        return cipher.login.matchesUri(targetUri, equivalentDomains, defaultUriMatch, overrideNeverMatchStrategy);
    }
    const login = cipher_view_like_utils_a.getLogin(cipher);
    if (!((_b = login === null || login === void 0 ? void 0 : login.uris) === null || _b === void 0 ? void 0 : _b.length)) {
        return false;
    }
    const loginUriViews = login.uris
        .filter((u) => !!u.uri)
        .map((u) => {
        var _b;
        const view = new LoginUriView();
        view.match = (_b = u.match) !== null && _b !== void 0 ? _b : defaultUriMatch;
        view.uri = u.uri; // above `filter` ensures `u.uri` is not null or undefined
        return view;
    });
    return loginUriViews.some((uriView) => uriView.matchesUri(targetUri, equivalentDomains, defaultUriMatch, overrideNeverMatchStrategy));
};
/** @returns true when the `copyField` is populated on the given cipher. */
CipherViewLikeUtils.hasCopyableValue = (cipher, copyField) => {
    var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
    // `CipherListView` instances do not contain the values to be copied, but rather a list of copyable fields.
    // When the copy action is performed on a `CipherListView`, the full cipher will need to be decrypted.
    if (cipher_view_like_utils_a.isCipherListView(cipher)) {
        let _copyField = copyField;
        if (_copyField === "username" && cipher_view_like_utils_a.getType(cipher) === CipherType.Login) {
            _copyField = "usernameLogin";
        }
        else if (_copyField === "username" && cipher_view_like_utils_a.getType(cipher) === CipherType.Identity) {
            _copyField = "usernameIdentity";
        }
        return (_c = (_b = cipher.copyableFields) === null || _b === void 0 ? void 0 : _b.includes(copyActionToCopyableFieldMap[_copyField])) !== null && _c !== void 0 ? _c : false;
    }
    // When the full cipher is available, check the specific field
    switch (copyField) {
        case "username":
            return !!((_d = cipher.login) === null || _d === void 0 ? void 0 : _d.username) || !!((_e = cipher.identity) === null || _e === void 0 ? void 0 : _e.username);
        case "password":
            return !!((_f = cipher.login) === null || _f === void 0 ? void 0 : _f.password);
        case "totp":
            return !!((_g = cipher.login) === null || _g === void 0 ? void 0 : _g.totp);
        case "cardNumber":
            return !!((_h = cipher.card) === null || _h === void 0 ? void 0 : _h.number);
        case "securityCode":
            return !!((_j = cipher.card) === null || _j === void 0 ? void 0 : _j.code);
        case "email":
            return !!((_k = cipher.identity) === null || _k === void 0 ? void 0 : _k.email);
        case "phone":
            return !!((_l = cipher.identity) === null || _l === void 0 ? void 0 : _l.phone);
        case "address":
            return !!((_m = cipher.identity) === null || _m === void 0 ? void 0 : _m.fullAddressForCopy);
        case "secureNote":
            return !!cipher.notes;
        case "privateKey":
            return !!((_o = cipher.sshKey) === null || _o === void 0 ? void 0 : _o.privateKey);
        case "publicKey":
            return !!((_p = cipher.sshKey) === null || _p === void 0 ? void 0 : _p.publicKey);
        case "keyFingerprint":
            return !!((_q = cipher.sshKey) === null || _q === void 0 ? void 0 : _q.keyFingerprint);
        default:
            return false;
    }
};
/** @returns true when the cipher has fido2 credentials */
CipherViewLikeUtils.hasFido2Credentials = (cipher) => {
    var _b;
    const login = cipher_view_like_utils_a.getLogin(cipher);
    return !!((_b = login === null || login === void 0 ? void 0 : login.fido2Credentials) === null || _b === void 0 ? void 0 : _b.length);
};
/**
 * Returns the `decryptionFailure` property from the cipher when available.
 * TODO: https://bitwarden.atlassian.net/browse/PM-22515 - alter for `CipherListView` if needed
 */
CipherViewLikeUtils.decryptionFailure = (cipher) => {
    return "decryptionFailure" in cipher ? cipher.decryptionFailure : false;
};
/**
 * Returns the notes from the cipher.
 *
 * @param cipher - The cipher to extract notes from (either `CipherView` or `CipherListView`)
 * @returns The notes string if present, or `undefined` if not set
 */
CipherViewLikeUtils.getNotes = (cipher) => {
    return cipher.notes;
};
/**
 * Returns the fields from the cipher.
 *
 * @param cipher - The cipher to extract fields from (either `CipherView` or `CipherListView`)
 * @returns Array of field objects with `name` and `value` properties, `undefined` if not set
 */
CipherViewLikeUtils.getFields = (cipher) => {
    if (cipher_view_like_utils_a.isCipherListView(cipher)) {
        return cipher.fields;
    }
    return cipher.fields;
};
/**
 * Returns attachment filenames from the cipher.
 *
 * @param cipher - The cipher to extract attachment names from (either `CipherView` or `CipherListView`)
 * @returns Array of attachment filenames, `undefined` if attachments are not present
 */
CipherViewLikeUtils.getAttachmentNames = (cipher) => {
    var _b;
    if (cipher_view_like_utils_a.isCipherListView(cipher)) {
        return cipher.attachmentNames;
    }
    return (_b = cipher.attachments) === null || _b === void 0 ? void 0 : _b.map((a) => a.fileName).filter((name) => name != null);
};
/**
 * Extracts hostname from a login URI.
 *
 * @param uri - The URI object (either `LoginUriView` class or `LoginListUriView`)
 * @returns The hostname if available, `undefined` otherwise
 *
 * @remarks
 * - For `LoginUriView` (CipherView): Uses the built-in `hostname` getter
 * - For `LoginListUriView` (CipherListView): Computes hostname using `Utils.getHostname()`
 * - Returns `undefined` for RegularExpression match types or when hostname cannot be extracted
 */
CipherViewLikeUtils.getUriHostname = (uri) => {
    var _b;
    if ("hostname" in uri && typeof uri.hostname !== "undefined") {
        return (_b = uri.hostname) !== null && _b !== void 0 ? _b : undefined;
    }
    if (uri.match !== domain_service_UriMatchStrategy.RegularExpression && uri.uri) {
        const hostname = utils_Utils.getHostname(uri.uri);
        return hostname === "" ? undefined : hostname;
    }
    return undefined;
};
/**
 * Mapping between the generic copy actions and the specific fields in a `CipherViewLike`.
 */
const copyActionToCopyableFieldMap = {
    usernameLogin: "LoginUsername",
    password: "LoginPassword",
    totp: "LoginTotp",
    cardNumber: "CardNumber",
    securityCode: "CardSecurityCode",
    usernameIdentity: "IdentityUsername",
    email: "IdentityEmail",
    phone: "IdentityPhone",
    address: "IdentityAddress",
    secureNote: "SecureNotes",
    privateKey: "SshKey",
    publicKey: "SshKey",
    keyFingerprint: "SshKey",
};
/** Converts a `LoginListUriView` to a `LoginUriView`. */
const toLoginUriView = (uri) => {
    if (uri instanceof LoginUriView) {
        return uri;
    }
    const loginUriView = new LoginUriView();
    if (uri.match) {
        loginUriView.match = uri.match;
    }
    if (uri.uri) {
        loginUriView.uri = uri.uri;
    }
    return loginUriView;
};

;// ./src/vault/archive.command.ts
var archive_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};




class ArchiveCommand {
    constructor(cipherService, accountService, cipherArchiveService, billingAccountProfileStateService) {
        this.cipherService = cipherService;
        this.accountService = accountService;
        this.cipherArchiveService = cipherArchiveService;
        this.billingAccountProfileStateService = billingAccountProfileStateService;
    }
    run(object, id) {
        return archive_command_awaiter(this, void 0, void 0, function* () {
            if (id != null) {
                id = id.toLowerCase();
            }
            const normalizedObject = object.toLowerCase();
            if (normalizedObject === "item") {
                return this.archiveCipher(id);
            }
            return response_Response.badRequest("Unknown object.");
        });
    }
    archiveCipher(cipherId) {
        return archive_command_awaiter(this, void 0, void 0, function* () {
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
            const cipher = yield this.cipherService.get(cipherId, activeUserId);
            if (cipher == null) {
                return response_Response.notFound();
            }
            const cipherView = yield this.cipherService.decrypt(cipher, activeUserId);
            const { canArchive, errorMessage } = yield this.userCanArchiveCipher(cipherView, activeUserId);
            if (!canArchive) {
                return response_Response.error(errorMessage);
            }
            try {
                yield this.cipherArchiveService.archiveWithServer(cipherView.id, activeUserId);
                return response_Response.success();
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
    /**
     * Determines if the user can archive the given cipher.
     * When the user cannot archive the cipher, an appropriate error message is provided.
     */
    userCanArchiveCipher(cipher, userId) {
        return archive_command_awaiter(this, void 0, void 0, function* () {
            const hasPremiumFromAnySource = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.billingAccountProfileStateService.hasPremiumFromAnySource$(userId));
            switch (true) {
                case !hasPremiumFromAnySource: {
                    return {
                        canArchive: false,
                        errorMessage: "Premium status is required to use this feature.",
                    };
                }
                case CipherViewLikeUtils.isArchived(cipher): {
                    return { canArchive: false, errorMessage: "Item is already archived." };
                }
                case CipherViewLikeUtils.isDeleted(cipher): {
                    return {
                        canArchive: false,
                        errorMessage: "Item is in the trash, the item must be restored before archiving.",
                    };
                }
                default:
                    return { canArchive: true };
            }
        });
    }
}

;// ./src/vault/create.command.ts
var vault_create_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
















class CreateCommand {
    constructor(cipherService, folderService, keyService, encryptService, apiService, folderApiService, accountProfileService, organizationService, accountService, cliRestrictedItemTypesService) {
        this.cipherService = cipherService;
        this.folderService = folderService;
        this.keyService = keyService;
        this.encryptService = encryptService;
        this.apiService = apiService;
        this.folderApiService = folderApiService;
        this.accountProfileService = accountProfileService;
        this.organizationService = organizationService;
        this.accountService = accountService;
        this.cliRestrictedItemTypesService = cliRestrictedItemTypesService;
    }
    run(object_1, requestJson_1, cmdOptions_1) {
        return vault_create_command_awaiter(this, arguments, void 0, function* (object, requestJson, cmdOptions, additionalData = null) {
            let req = null;
            if (object !== "attachment") {
                if (process.env.BW_SERVE !== "true" && (requestJson == null || requestJson === "")) {
                    requestJson = yield CliUtils.readStdin();
                }
                if (requestJson == null || requestJson === "") {
                    return response_Response.badRequest("`requestJson` was not provided.");
                }
                if (typeof requestJson !== "string") {
                    req = requestJson;
                }
                else {
                    try {
                        const reqJson = Buffer.from(requestJson, "base64").toString();
                        req = JSON.parse(reqJson);
                        // FIXME: Remove when updating file. Eslint update
                        // eslint-disable-next-line @typescript-eslint/no-unused-vars
                    }
                    catch (e) {
                        return response_Response.badRequest("Error parsing the encoded request data.");
                    }
                }
            }
            const normalizedOptions = new vault_create_command_Options(cmdOptions);
            switch (object.toLowerCase()) {
                case "item":
                    return yield this.createCipher(req);
                case "attachment":
                    return yield this.createAttachment(normalizedOptions, additionalData);
                case "folder":
                    return yield this.createFolder(req);
                case "org-collection":
                    return yield this.createOrganizationCollection(req, normalizedOptions);
                default:
                    return response_Response.badRequest("Unknown object.");
            }
        });
    }
    createCipher(req) {
        return vault_create_command_awaiter(this, void 0, void 0, function* () {
            try {
                const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
                const cipherView = CipherExport.toView(req);
                const isCipherTypeRestricted = yield this.cliRestrictedItemTypesService.isCipherRestricted(cipherView);
                if (isCipherTypeRestricted) {
                    return response_Response.error("Creating this item type is restricted by organizational policy.");
                }
                const newCipher = yield this.cipherService.createWithServer(CipherExport.toView(req), activeUserId);
                const res = new CipherResponse(newCipher);
                return response_Response.success(res);
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
    createAttachment(options, additionalData) {
        return vault_create_command_awaiter(this, void 0, void 0, function* () {
            if (options.itemId == null || options.itemId === "") {
                return response_Response.badRequest("`itemid` option is required.");
            }
            let fileBuf = null;
            let fileName = null;
            if (process.env.BW_SERVE === "true") {
                fileBuf = additionalData.fileBuffer;
                fileName = additionalData.fileName;
            }
            else {
                if (options.file == null || options.file === "") {
                    return response_Response.badRequest("`file` option is required.");
                }
                const filePath = external_path_namespaceObject.resolve(options.file);
                if (!external_fs_namespaceObject.existsSync(options.file)) {
                    return response_Response.badRequest("Cannot find file at " + filePath);
                }
                fileBuf = external_fs_namespaceObject.readFileSync(filePath);
                fileName = external_path_namespaceObject.basename(filePath);
            }
            if (fileBuf == null) {
                return response_Response.badRequest("File not provided.");
            }
            if (fileName == null || fileName.trim() === "") {
                return response_Response.badRequest("File name not provided.");
            }
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
            const itemId = options.itemId.toLowerCase();
            const cipher = yield this.cipherService.get(itemId, activeUserId);
            if (cipher == null) {
                return response_Response.notFound();
            }
            const canAccessPremium = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountProfileService.hasPremiumFromAnySource$(activeUserId));
            if (cipher.organizationId == null && !canAccessPremium) {
                return response_Response.error("Premium status is required to use this feature.");
            }
            const userKey = yield this.keyService.getUserKey();
            if (userKey == null) {
                return response_Response.error("You must update your encryption key before you can use this feature. " +
                    "See https://help.bitwarden.com/article/update-encryption-key/");
            }
            try {
                const updatedCipher = yield this.cipherService.saveAttachmentRawWithServer(cipher, fileName, new Uint8Array(fileBuf), activeUserId);
                const decCipher = yield this.cipherService.decrypt(updatedCipher, activeUserId);
                return response_Response.success(new CipherResponse(decCipher));
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
    createFolder(req) {
        return vault_create_command_awaiter(this, void 0, void 0, function* () {
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
            const userKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.userKey$(activeUserId));
            const folder = yield this.folderService.encrypt(FolderExport.toView(req), userKey);
            try {
                const folderData = yield this.folderApiService.save(folder, activeUserId);
                const newFolder = new Folder(folderData);
                const decFolder = yield newFolder.decrypt(userKey);
                const res = new FolderResponse(decFolder);
                return response_Response.success(res);
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
    createOrganizationCollection(req, options) {
        return vault_create_command_awaiter(this, void 0, void 0, function* () {
            if (options.organizationId == null || options.organizationId === "") {
                return response_Response.badRequest("`organizationid` option is required.");
            }
            if (!utils_Utils.isGuid(options.organizationId)) {
                return response_Response.badRequest("`" + options.organizationId + "` is not a GUID.");
            }
            if (options.organizationId !== req.organizationId) {
                return response_Response.badRequest("`organizationid` option does not match request object.");
            }
            if (req.name == null || req.name.trim() === "") {
                return response_Response.badRequest("Collection name is required.");
            }
            try {
                const orgKey = yield this.keyService.getOrgKey(req.organizationId);
                if (orgKey == null) {
                    throw new Error("No encryption key for this organization.");
                }
                const userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.map)((a) => a === null || a === void 0 ? void 0 : a.id)));
                if (!userId) {
                    return response_Response.badRequest("No user found.");
                }
                const organization = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.organizationService
                    .organizations$(userId)
                    .pipe((0,external_rxjs_namespaceObject.map)((organizations) => organizations.find((o) => o.id === req.organizationId))));
                const currentOrgUserId = organization.organizationUserId;
                const groups = req.groups == null
                    ? null
                    : req.groups.map((g) => new selection_read_only_request_SelectionReadOnlyRequest(g.id, g.readOnly, g.hidePasswords, g.manage));
                const users = req.users == null
                    ? [new selection_read_only_request_SelectionReadOnlyRequest(currentOrgUserId, false, false, true)]
                    : req.users.map((u) => new selection_read_only_request_SelectionReadOnlyRequest(u.id, u.readOnly, u.hidePasswords, u.manage));
                const request = new collection_request_CreateCollectionRequest({
                    name: yield this.encryptService.encryptString(req.name, orgKey),
                    externalId: req.externalId,
                    groups,
                    users,
                });
                const response = yield this.apiService.postCollection(req.organizationId, request);
                const view = CollectionExport.toView(req, response.id);
                const res = new OrganizationCollectionResponse(view, groups, users);
                return response_Response.success(res);
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
}
class vault_create_command_Options {
    constructor(passedOptions) {
        this.organizationId = (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.organizationid) || (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.organizationId);
        this.itemId = (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.itemid) || (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.itemId);
        this.file = passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.file;
    }
}

;// ./src/vault/delete.command.ts
var vault_delete_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore





class DeleteCommand {
    constructor(cipherService, folderService, apiService, folderApiService, accountProfileService, cipherAuthorizationService, accountService, cliRestrictedItemTypesService) {
        this.cipherService = cipherService;
        this.folderService = folderService;
        this.apiService = apiService;
        this.folderApiService = folderApiService;
        this.accountProfileService = accountProfileService;
        this.cipherAuthorizationService = cipherAuthorizationService;
        this.accountService = accountService;
        this.cliRestrictedItemTypesService = cliRestrictedItemTypesService;
    }
    run(object, id, cmdOptions) {
        return vault_delete_command_awaiter(this, void 0, void 0, function* () {
            if (id != null) {
                id = id.toLowerCase();
            }
            const normalizedOptions = new delete_command_Options(cmdOptions);
            switch (object.toLowerCase()) {
                case "item":
                    return yield this.deleteCipher(id, normalizedOptions);
                case "attachment":
                    return yield this.deleteAttachment(id, normalizedOptions);
                case "folder":
                    return yield this.deleteFolder(id);
                case "org-collection":
                    return yield this.deleteOrganizationCollection(id, normalizedOptions);
                default:
                    return response_Response.badRequest("Unknown object.");
            }
        });
    }
    deleteCipher(id, options) {
        return vault_delete_command_awaiter(this, void 0, void 0, function* () {
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
            const cipher = yield this.cipherService.get(id, activeUserId);
            if (cipher == null) {
                return response_Response.notFound();
            }
            const canDeleteCipher = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.cipherAuthorizationService.canDeleteCipher$(cipher));
            if (!canDeleteCipher) {
                return response_Response.error("You do not have permission to delete this item.");
            }
            const isCipherTypeRestricted = yield this.cliRestrictedItemTypesService.isCipherRestricted(cipher);
            if (isCipherTypeRestricted) {
                return response_Response.error("Deleting this item type is restricted by organizational policy.");
            }
            try {
                if (options.permanent) {
                    yield this.cipherService.deleteWithServer(id, activeUserId);
                }
                else {
                    yield this.cipherService.softDeleteWithServer(id, activeUserId);
                }
                return response_Response.success();
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
    deleteAttachment(id, options) {
        return vault_delete_command_awaiter(this, void 0, void 0, function* () {
            if (options.itemId == null || options.itemId === "") {
                return response_Response.badRequest("`itemid` option is required.");
            }
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
            const itemId = options.itemId.toLowerCase();
            const cipher = yield this.cipherService.get(itemId, activeUserId);
            if (cipher == null) {
                return response_Response.notFound();
            }
            if (cipher.attachments == null || cipher.attachments.length === 0) {
                return response_Response.error("No attachments available for this item.");
            }
            const attachments = cipher.attachments.filter((a) => a.id.toLowerCase() === id);
            if (attachments.length === 0) {
                return response_Response.error("Attachment `" + id + "` was not found.");
            }
            const canAccessPremium = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountProfileService.hasPremiumFromAnySource$(activeUserId));
            if (cipher.organizationId == null && !canAccessPremium) {
                return response_Response.error("Premium status is required to use this feature.");
            }
            try {
                yield this.cipherService.deleteAttachmentWithServer(cipher.id, attachments[0].id, activeUserId, false);
                return response_Response.success();
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
    deleteFolder(id) {
        return vault_delete_command_awaiter(this, void 0, void 0, function* () {
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
            const folder = yield this.folderService.getFromState(id, activeUserId);
            if (folder == null) {
                return response_Response.notFound();
            }
            try {
                yield this.folderApiService.delete(id, activeUserId);
                return response_Response.success();
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
    deleteOrganizationCollection(id, options) {
        return vault_delete_command_awaiter(this, void 0, void 0, function* () {
            if (options.organizationId == null || options.organizationId === "") {
                return response_Response.badRequest("`organizationid` options is required.");
            }
            if (!utils_Utils.isGuid(id)) {
                return response_Response.badRequest("`" + id + "` is not a GUID.");
            }
            if (!utils_Utils.isGuid(options.organizationId)) {
                return response_Response.badRequest("`" + options.organizationId + "` is not a GUID.");
            }
            try {
                yield this.apiService.deleteCollection(options.organizationId, id);
                return response_Response.success();
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
}
class delete_command_Options {
    constructor(passedOptions) {
        this.organizationId = (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.organizationid) || (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.organizationId);
        this.itemId = (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.itemid) || (passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.itemId);
        this.permanent = CliUtils.convertBooleanOption(passedOptions === null || passedOptions === void 0 ? void 0 : passedOptions.permanent);
    }
}

;// ./src/vault.program.ts
var vault_program_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore















const vault_program_writeLn = CliUtils.writeLn;
class VaultProgram extends BaseProgram {
    register() {
        return vault_program_awaiter(this, void 0, void 0, function* () {
            external_commander_namespaceObject.program
                .addCommand(this.listCommand())
                .addCommand(this.getCommand())
                .addCommand(this.createCommand())
                .addCommand(this.editCommand())
                .addCommand(this.deleteCommand())
                .addCommand(this.restoreCommand())
                .addCommand(this.shareCommand("move", false))
                .addCommand(this.confirmCommand())
                .addCommand(this.importCommand())
                .addCommand(this.exportCommand())
                .addCommand(this.shareCommand("share", true))
                .addCommand(this.archiveCommand());
        });
    }
    validateObject(requestedObject, validObjects) {
        let success = true;
        if (!validObjects.includes(requestedObject)) {
            success = false;
            this.processResponse(response_Response.badRequest('Unknown object "' +
                requestedObject +
                '". Allowed objects are: ' +
                validObjects.join(", ") +
                "."));
        }
        return success;
    }
    listCommand() {
        const listObjects = [
            "items",
            "folders",
            "collections",
            "org-collections",
            "org-members",
            "organizations",
        ];
        const command = new external_commander_namespaceObject.Command("list")
            .argument("<object>", "Valid objects are: " + listObjects.join(", "))
            .description("List an array of objects from the vault.")
            .option("--search <search>", "Perform a search on the listed objects.")
            .option("--url <url>", "Filter items of type login with a url-match search.")
            .option("--folderid <folderid>", "Filter items by folder id.")
            .option("--collectionid <collectionid>", "Filter items by collection id.")
            .option("--organizationid <organizationid>", "Filter items or collections by organization id.")
            .option("--trash", "Filter items that are deleted and in the trash.")
            .on("--help", () => {
            vault_program_writeLn("\n  Notes:");
            vault_program_writeLn("");
            vault_program_writeLn("    Combining search with a filter performs a logical AND operation.");
            vault_program_writeLn("");
            vault_program_writeLn("    Combining multiple filters performs a logical OR operation.");
            vault_program_writeLn("");
            vault_program_writeLn("  Examples:");
            vault_program_writeLn("");
            vault_program_writeLn("    bw list items");
            vault_program_writeLn("    bw list items --folderid 60556c31-e649-4b5d-8daf-fc1c391a1bf2");
            vault_program_writeLn("    bw list items --search google --folderid 60556c31-e649-4b5d-8daf-fc1c391a1bf2");
            vault_program_writeLn("    bw list items --url https://google.com");
            vault_program_writeLn("    bw list items --folderid null");
            vault_program_writeLn("    bw list items --organizationid notnull");
            vault_program_writeLn("    bw list items --folderid 60556c31-e649-4b5d-8daf-fc1c391a1bf2 --organizationid notnull");
            vault_program_writeLn("    bw list items --trash");
            vault_program_writeLn("    bw list items --archived");
            vault_program_writeLn("    bw list folders --search email");
            vault_program_writeLn("    bw list org-members --organizationid 60556c31-e649-4b5d-8daf-fc1c391a1bf2");
            vault_program_writeLn("", true);
        })
            .action((object, cmd) => vault_program_awaiter(this, void 0, void 0, function* () {
            if (!this.validateObject(object, listObjects)) {
                return;
            }
            yield this.exitIfLocked();
            const command = new ListCommand(this.serviceContainer.cipherService, this.serviceContainer.folderService, this.serviceContainer.collectionService, this.serviceContainer.organizationService, this.serviceContainer.searchService, this.serviceContainer.organizationUserApiService, this.serviceContainer.apiService, this.serviceContainer.eventCollectionService, this.serviceContainer.accountService, this.serviceContainer.keyService, this.serviceContainer.cliRestrictedItemTypesService, this.serviceContainer.cipherArchiveService);
            const response = yield command.run(object, cmd);
            this.processResponse(response);
        }));
        command.option("--archived", "Filter items that are archived.");
        return command;
    }
    getCommand() {
        const getObjects = [
            "item",
            "username",
            "password",
            "uri",
            "totp",
            "notes",
            "exposed",
            "attachment",
            "folder",
            "collection",
            "org-collection",
            "organization",
            "template",
            "fingerprint",
            "send",
        ];
        return new external_commander_namespaceObject.Command("get")
            .argument("<object>", "Valid objects are: " + getObjects.join(", "))
            .argument("<id>", "Search term or object's globally unique `id`.")
            .description("Get an object from the vault.")
            .option("--itemid <itemid>", "Attachment's item id.")
            .option("--output <output>", "Output directory or filename for attachment.")
            .option("--organizationid <organizationid>", "Organization id for an organization object.")
            .on("--help", () => {
            vault_program_writeLn("\n  If raw output is specified and no output filename or directory is given for");
            vault_program_writeLn("  an attachment query, the attachment content is written to stdout.");
            vault_program_writeLn("");
            vault_program_writeLn("  Examples:");
            vault_program_writeLn("");
            vault_program_writeLn("    bw get item 99ee88d2-6046-4ea7-92c2-acac464b1412");
            vault_program_writeLn("    bw get password https://google.com");
            vault_program_writeLn("    bw get totp google.com");
            vault_program_writeLn("    bw get notes google.com");
            vault_program_writeLn("    bw get exposed yahoo.com");
            vault_program_writeLn("    bw get attachment b857igwl1dzrs2 --itemid 99ee88d2-6046-4ea7-92c2-acac464b1412 " +
                "--output ./photo.jpg");
            vault_program_writeLn("    bw get attachment photo.jpg --itemid 99ee88d2-6046-4ea7-92c2-acac464b1412 --raw");
            vault_program_writeLn("    bw get folder email");
            vault_program_writeLn("    bw get template folder");
            vault_program_writeLn("", true);
        })
            .action((object, id, cmd) => vault_program_awaiter(this, void 0, void 0, function* () {
            if (!this.validateObject(object, getObjects)) {
                return;
            }
            yield this.exitIfLocked();
            const command = new GetCommand(this.serviceContainer.cipherService, this.serviceContainer.folderService, this.serviceContainer.collectionService, this.serviceContainer.totpService, this.serviceContainer.auditService, this.serviceContainer.keyService, this.serviceContainer.encryptService, this.serviceContainer.searchService, this.serviceContainer.apiService, this.serviceContainer.organizationService, this.serviceContainer.eventCollectionService, this.serviceContainer.billingAccountProfileStateService, this.serviceContainer.accountService, this.serviceContainer.cliRestrictedItemTypesService);
            const response = yield command.run(object, id, cmd);
            this.processResponse(response);
        }));
    }
    createCommand() {
        const createObjects = ["item", "attachment", "folder", "org-collection"];
        return new external_commander_namespaceObject.Command("create")
            .argument("<object>", "Valid objects are: " + createObjects.join(", "))
            .argument("[encodedJson]", "Encoded json of the object to create. Can also be piped into stdin.")
            .description("Create an object in the vault.")
            .option("--file <file>", "Path to file for attachment.")
            .option("--itemid <itemid>", "Attachment's item id.")
            .option("--organizationid <organizationid>", "Organization id for an organization object.")
            .on("--help", () => {
            vault_program_writeLn("\n  Examples:");
            vault_program_writeLn("");
            vault_program_writeLn("    bw create folder eyJuYW1lIjoiTXkgRm9sZGVyIn0K");
            vault_program_writeLn("    echo 'eyJuYW1lIjoiTXkgRm9sZGVyIn0K' | bw create folder");
            vault_program_writeLn("    bw create attachment --file ./myfile.csv " +
                "--itemid 16b15b89-65b3-4639-ad2a-95052a6d8f66");
            vault_program_writeLn("", true);
        })
            .action((object, encodedJson, cmd) => vault_program_awaiter(this, void 0, void 0, function* () {
            if (!this.validateObject(object, createObjects)) {
                return;
            }
            yield this.exitIfLocked();
            const command = new CreateCommand(this.serviceContainer.cipherService, this.serviceContainer.folderService, this.serviceContainer.keyService, this.serviceContainer.encryptService, this.serviceContainer.apiService, this.serviceContainer.folderApiService, this.serviceContainer.billingAccountProfileStateService, this.serviceContainer.organizationService, this.serviceContainer.accountService, this.serviceContainer.cliRestrictedItemTypesService);
            const response = yield command.run(object, encodedJson, cmd);
            this.processResponse(response);
        }));
    }
    editCommand() {
        const editObjects = ["item", "item-collections", "folder", "org-collection"];
        return new external_commander_namespaceObject.Command("edit")
            .argument("<object>", "Valid objects are: " + editObjects.join(", "))
            .argument("<id>", "Object's globally unique `id`.")
            .argument("[encodedJson]", "Encoded json of the object to create. Can also be piped into stdin.")
            .description("Edit an object from the vault.")
            .option("--organizationid <organizationid>", "Organization id for an organization object.")
            .on("--help", () => {
            vault_program_writeLn("\n  Examples:");
            vault_program_writeLn("");
            vault_program_writeLn("    bw edit folder 5cdfbd80-d99f-409b-915b-f4c5d0241b02 eyJuYW1lIjoiTXkgRm9sZGVyMiJ9Cg==");
            vault_program_writeLn("    echo 'eyJuYW1lIjoiTXkgRm9sZGVyMiJ9Cg==' | " +
                "bw edit folder 5cdfbd80-d99f-409b-915b-f4c5d0241b02");
            vault_program_writeLn("    bw edit item-collections 78307355-fd25-416b-88b8-b33fd0e88c82 " +
                "WyI5NzQwNTNkMC0zYjMzLTRiOTgtODg2ZS1mZWNmNWM4ZGJhOTYiXQ==");
            vault_program_writeLn("", true);
        })
            .action((object, id, encodedJson, cmd) => vault_program_awaiter(this, void 0, void 0, function* () {
            if (!this.validateObject(object, editObjects)) {
                return;
            }
            yield this.exitIfLocked();
            const command = new EditCommand(this.serviceContainer.cipherService, this.serviceContainer.folderService, this.serviceContainer.keyService, this.serviceContainer.encryptService, this.serviceContainer.apiService, this.serviceContainer.folderApiService, this.serviceContainer.accountService, this.serviceContainer.cliRestrictedItemTypesService, this.serviceContainer.policyService, this.serviceContainer.billingAccountProfileStateService);
            const response = yield command.run(object, id, encodedJson, cmd);
            this.processResponse(response);
        }));
    }
    deleteCommand() {
        const deleteObjects = ["item", "attachment", "folder", "org-collection"];
        return new external_commander_namespaceObject.Command("delete")
            .argument("<object>", "Valid objects are: " + deleteObjects.join(", "))
            .argument("<id>", "Object's globally unique `id`.")
            .description("Delete an object from the vault.")
            .option("--itemid <itemid>", "Attachment's item id.")
            .option("--organizationid <organizationid>", "Organization id for an organization object.")
            .option("-p, --permanent", "Permanently deletes the item instead of soft-deleting it (item only).")
            .on("--help", () => {
            vault_program_writeLn("\n  Examples:");
            vault_program_writeLn("");
            vault_program_writeLn("    bw delete item 7063feab-4b10-472e-b64c-785e2b870b92");
            vault_program_writeLn("    bw delete item 89c21cd2-fab0-4f69-8c6e-ab8a0168f69a --permanent");
            vault_program_writeLn("    bw delete folder 5cdfbd80-d99f-409b-915b-f4c5d0241b02");
            vault_program_writeLn("    bw delete attachment b857igwl1dzrs2 --itemid 310d5ffd-e9a2-4451-af87-ea054dce0f78");
            vault_program_writeLn("", true);
        })
            .action((object, id, cmd) => vault_program_awaiter(this, void 0, void 0, function* () {
            if (!this.validateObject(object, deleteObjects)) {
                return;
            }
            yield this.exitIfLocked();
            const command = new DeleteCommand(this.serviceContainer.cipherService, this.serviceContainer.folderService, this.serviceContainer.apiService, this.serviceContainer.folderApiService, this.serviceContainer.billingAccountProfileStateService, this.serviceContainer.cipherAuthorizationService, this.serviceContainer.accountService, this.serviceContainer.cliRestrictedItemTypesService);
            const response = yield command.run(object, id, cmd);
            this.processResponse(response);
        }));
    }
    archiveCommand() {
        const archiveObjects = ["item"];
        return new external_commander_namespaceObject.Command("archive")
            .argument("<object>", "Valid objects are: " + archiveObjects.join(", "))
            .argument("<id>", "Object's globally unique `id`.")
            .description("Archive an object from the vault.")
            .on("--help", () => {
            vault_program_writeLn("\n  Examples:");
            vault_program_writeLn("");
            vault_program_writeLn("    bw archive item 7063feab-4b10-472e-b64c-785e2b870b92");
            vault_program_writeLn("", true);
        })
            .action((object, id) => vault_program_awaiter(this, void 0, void 0, function* () {
            if (!this.validateObject(object, archiveObjects)) {
                return;
            }
            yield this.exitIfLocked();
            const command = new ArchiveCommand(this.serviceContainer.cipherService, this.serviceContainer.accountService, this.serviceContainer.cipherArchiveService, this.serviceContainer.billingAccountProfileStateService);
            const response = yield command.run(object, id);
            this.processResponse(response);
        }));
    }
    restoreCommand() {
        const restoreObjects = ["item"];
        return new external_commander_namespaceObject.Command("restore")
            .argument("<object>", "Valid objects are: " + restoreObjects.join(", "))
            .argument("<id>", "Object's globally unique `id`.")
            .description("Restores an object from the trash or archive.")
            .on("--help", () => {
            vault_program_writeLn("\n  Examples:");
            vault_program_writeLn("");
            vault_program_writeLn("    bw restore item 7063feab-4b10-472e-b64c-785e2b870b92");
            vault_program_writeLn("", true);
        })
            .action((object, id, cmd) => vault_program_awaiter(this, void 0, void 0, function* () {
            if (!this.validateObject(object, restoreObjects)) {
                return;
            }
            yield this.exitIfLocked();
            const command = new RestoreCommand(this.serviceContainer.cipherService, this.serviceContainer.accountService, this.serviceContainer.cipherAuthorizationService, this.serviceContainer.cipherArchiveService);
            const response = yield command.run(object, id);
            this.processResponse(response);
        }));
    }
    shareCommand(commandName, deprecated) {
        return new external_commander_namespaceObject.Command(commandName)
            .argument("<id>", "Object's globally unique `id`.")
            .argument("<organizationId>", "Organization's globally unique `id`.")
            .argument("[encodedJson]", "Encoded json of an array of collection ids. Can also be piped into stdin.")
            .description((deprecated ? "--DEPRECATED-- " : "") + "Move an item to an organization.")
            .on("--help", () => {
            vault_program_writeLn("\n  Examples:");
            vault_program_writeLn("");
            vault_program_writeLn("    bw " +
                commandName +
                " 4af958ce-96a7-45d9-beed-1e70fabaa27a " +
                "6d82949b-b44d-468a-adae-3f3bacb0ea32 WyI5NzQwNTNkMC0zYjMzLTRiOTgtODg2ZS1mZWNmNWM4ZGJhOTYiXQ==");
            vault_program_writeLn("    echo '[\"974053d0-3b33-4b98-886e-fecf5c8dba96\"]' | bw encode | " +
                "bw " +
                commandName +
                " 4af958ce-96a7-45d9-beed-1e70fabaa27a 6d82949b-b44d-468a-adae-3f3bacb0ea32");
            if (deprecated) {
                vault_program_writeLn("");
                vault_program_writeLn('--DEPRECATED See "bw move" for the current implementation--');
            }
            vault_program_writeLn("", true);
        })
            .action((id, organizationId, encodedJson, cmd) => vault_program_awaiter(this, void 0, void 0, function* () {
            yield this.exitIfLocked();
            const command = new ShareCommand(this.serviceContainer.cipherService, this.serviceContainer.accountService);
            const response = yield command.run(id, organizationId, encodedJson);
            this.processResponse(response);
        }));
    }
    confirmCommand() {
        const confirmObjects = ["org-member"];
        return new external_commander_namespaceObject.Command("confirm")
            .argument("<object>", "Valid objects are: " + confirmObjects.join(", "))
            .argument("<id>", "Object's globally unique `id`.")
            .description("Confirm an object to the organization.")
            .option("--organizationid <organizationid>", "Organization id for an organization object.")
            .on("--help", () => {
            vault_program_writeLn("\n  Examples:");
            vault_program_writeLn("");
            vault_program_writeLn("    bw confirm org-member 7063feab-4b10-472e-b64c-785e2b870b92 " +
                "--organizationid 310d5ffd-e9a2-4451-af87-ea054dce0f78");
            vault_program_writeLn("", true);
        })
            .action((object, id, cmd) => vault_program_awaiter(this, void 0, void 0, function* () {
            if (!this.validateObject(object, confirmObjects)) {
                return;
            }
            yield this.exitIfLocked();
            const command = new ConfirmCommand(this.serviceContainer.apiService, this.serviceContainer.keyService, this.serviceContainer.encryptService, this.serviceContainer.organizationUserApiService, this.serviceContainer.accountService, this.serviceContainer.i18nService);
            const response = yield command.run(object, id, cmd);
            this.processResponse(response);
        }));
    }
    importCommand() {
        return new external_commander_namespaceObject.Command("import")
            .argument("[format]", "The format of [input]")
            .argument("[input]", "Filepath to data to import")
            .description("Import vault data from a file.")
            .option("--formats", "List formats")
            .option("--organizationid <organizationid>", "ID of the organization to import to.")
            .on("--help", () => {
            vault_program_writeLn("\n Examples:");
            vault_program_writeLn("");
            vault_program_writeLn("    bw import --formats");
            vault_program_writeLn("    bw import bitwardencsv ./from/source.csv");
            vault_program_writeLn("    bw import keepass2xml keepass_backup.xml");
            vault_program_writeLn("    bw import --organizationid cf14adc3-aca5-4573-890a-f6fa231436d9 keepass2xml keepass_backup.xml");
        })
            .action((format, filepath, options) => vault_program_awaiter(this, void 0, void 0, function* () {
            yield this.exitIfLocked();
            const command = new ImportCommand(this.serviceContainer.importService, this.serviceContainer.organizationService, this.serviceContainer.syncService, this.serviceContainer.accountService);
            const response = yield command.run(format, filepath, options);
            this.processResponse(response);
        }));
    }
    exportCommand() {
        return new external_commander_namespaceObject.Command("export")
            .description("Export vault data to a CSV, JSON or ZIP file.")
            .option("--output <output>", "Output directory or filename.")
            .option("--format <format>", "Export file format.")
            .option("--password [password]", "Use password to encrypt instead of your Bitwarden account encryption key. Only applies to the encrypted_json format.")
            .option("--organizationid <organizationid>", "Organization id for an organization.")
            .on("--help", () => {
            vault_program_writeLn("\n  Notes:");
            vault_program_writeLn("");
            vault_program_writeLn("    Valid formats are `csv`, `json`, `encrypted_json` and zip. Default format is `csv`.");
            vault_program_writeLn("");
            vault_program_writeLn("    If --raw option is specified and no output filename or directory is given, the");
            vault_program_writeLn("    result is written to stdout.");
            vault_program_writeLn("");
            vault_program_writeLn("  Examples:");
            vault_program_writeLn("");
            vault_program_writeLn("    bw export");
            vault_program_writeLn("    bw --raw export");
            vault_program_writeLn("    bw export myPassword321");
            vault_program_writeLn("    bw export myPassword321 --format json");
            vault_program_writeLn("    bw export --output ./exp/bw.csv");
            vault_program_writeLn("    bw export myPassword321 --output bw.json --format json");
            vault_program_writeLn("    bw export myPassword321 --organizationid 7063feab-4b10-472e-b64c-785e2b870b92");
            vault_program_writeLn("", true);
        })
            .action((options) => vault_program_awaiter(this, void 0, void 0, function* () {
            yield this.exitIfLocked();
            const command = new ExportCommand(this.serviceContainer.exportService, this.serviceContainer.policyService, this.serviceContainer.eventCollectionService, this.serviceContainer.accountService);
            const response = yield command.run(options);
            this.processResponse(response);
        }));
    }
}

;// ./src/register-oss-programs.ts
var register_oss_programs_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};



/**
 * All OSS licensed programs should be registered here.
 * @example
 * const myProgram = new myProgram(serviceContainer);
 * myProgram.register();
 * @param serviceContainer A class that instantiates services and makes them available for dependency injection
 */
function registerOssPrograms(serviceContainer) {
    return register_oss_programs_awaiter(this, void 0, void 0, function* () {
        const program = new Program(serviceContainer);
        yield program.register();
        const vaultProgram = new VaultProgram(serviceContainer);
        yield vaultProgram.register();
        const sendProgram = new SendProgram(serviceContainer);
        yield sendProgram.register();
    });
}

;// external "node:http"
const external_node_http_namespaceObject = require("node:http");
var external_node_http_default = /*#__PURE__*/__webpack_require__.n(external_node_http_namespaceObject);
;// external "node:net"
const external_node_net_namespaceObject = require("node:net");
var external_node_net_default = /*#__PURE__*/__webpack_require__.n(external_node_net_namespaceObject);
;// external "@koa/router"
const router_namespaceObject = require("@koa/router");
;// external "koa"
const external_koa_namespaceObject = require("koa");
;// external "koa-bodyparser"
const external_koa_bodyparser_namespaceObject = require("koa-bodyparser");
;// external "koa-json"
const external_koa_json_namespaceObject = require("koa-json");
;// ./src/commands/serve.command.ts
var serve_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};







class ServeCommand {
    constructor(serviceContainer, serveConfigurator) {
        this.serviceContainer = serviceContainer;
        this.serveConfigurator = serveConfigurator;
    }
    run(options) {
        return serve_command_awaiter(this, void 0, void 0, function* () {
            const protectOrigin = !options.disableOriginProtection;
            const port = options.port || 8087;
            const hostname = options.hostname || "localhost";
            this.serviceContainer.logService.info(`Starting server on ${hostname}:${port} with ${protectOrigin ? "origin protection" : "no origin protection"}`);
            const server = new external_koa_namespaceObject();
            const router = new router_namespaceObject.Router();
            process.env.BW_SERVE = "true";
            process.env.BW_NOINTERACTION = "true";
            server
                .use((ctx, next) => serve_command_awaiter(this, void 0, void 0, function* () {
                if (protectOrigin && ctx.headers.origin != undefined) {
                    ctx.status = 403;
                    this.serviceContainer.logService.warning(`Blocking request from "${utils_Utils.isNullOrEmpty(ctx.headers.origin)
                        ? "(Origin header value missing)"
                        : ctx.headers.origin}"`);
                    return;
                }
                yield next();
            }))
                .use(external_koa_bodyparser_namespaceObject())
                .use(external_koa_json_namespaceObject({ pretty: false, param: "pretty" }));
            yield this.serveConfigurator.configureRouter(router);
            server.use(router.routes()).use(router.allowedMethods());
            if (hostname.startsWith("fd+connected://")) {
                const fd = parseInt(hostname.slice("fd+connected://".length));
                const httpServer = external_node_http_default().createServer(server.callback());
                const socket = new (external_node_net_default()).Socket({ fd: fd, readable: true, writable: true });
                // allow idle sockets, incomplete handshakes and slow requests
                httpServer.keepAliveTimeout = 0;
                httpServer.headersTimeout = 0;
                httpServer.timeout = 0;
                socket.pause();
                httpServer.emit("connection", socket);
                socket.resume(); // Let the HTTP parser start reading
            }
            else if (hostname.startsWith("fd+listening://")) {
                const fd = parseInt(hostname.slice("fd+listening://".length));
                server.listen({ fd }, () => {
                    this.serviceContainer.logService.info("Listening on " + hostname);
                });
            }
            else if (hostname.startsWith("unix://")) {
                const socketPath = hostname.slice("unix://".length);
                server.listen(socketPath, () => {
                    this.serviceContainer.logService.info("Listening on " + hostname);
                });
            }
            else {
                server.listen(port, hostname === "all" ? null : hostname, () => {
                    this.serviceContainer.logService.info("Listening on " + hostname + ":" + port);
                });
            }
        });
    }
}

;// ./src/serve.program.ts
var serve_program_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};




const serve_program_writeLn = CliUtils.writeLn;
class ServeProgram extends BaseProgram {
    constructor(serviceContainer, configurator) {
        super(serviceContainer);
        this.configurator = configurator;
    }
    register() {
        external_commander_namespaceObject.program
            .command("serve")
            .description("Start a RESTful API webserver.")
            .option("--hostname <hostname>", "The hostname to bind your API webserver to.")
            .option("--port <port>", "The port to run your API webserver on.")
            .option("--disable-origin-protection", "If set, allows requests with origin header. Warning, this option exists for backwards compatibility reasons and exposes your environment to known CSRF attacks.")
            .on("--help", () => {
            serve_program_writeLn("\n  Notes:");
            serve_program_writeLn("");
            serve_program_writeLn("    Default hostname is `localhost`.");
            serve_program_writeLn("    Use hostname `all` for no hostname binding.");
            serve_program_writeLn("    Default port is `8087`.");
            serve_program_writeLn("");
            serve_program_writeLn("  Examples:");
            serve_program_writeLn("");
            serve_program_writeLn("    bw serve");
            serve_program_writeLn("    bw serve --port 8080");
            serve_program_writeLn("    bw serve --hostname bwapi.mydomain.com --port 80");
            serve_program_writeLn("", true);
        })
            .action((cmd) => serve_program_awaiter(this, void 0, void 0, function* () {
            yield this.exitIfNotAuthed();
            const command = new ServeCommand(this.serviceContainer, this.configurator);
            yield command.run(cmd);
        }));
    }
}

;// external "@koa/multer"
const multer_namespaceObject = require("@koa/multer");
;// ./src/tools/send/index.ts


;// ./src/oss-serve-configurator.ts
var oss_serve_configurator_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore



















class OssServeConfigurator {
    constructor(serviceContainer) {
        this.serviceContainer = serviceContainer;
        this.getCommand = new GetCommand(this.serviceContainer.cipherService, this.serviceContainer.folderService, this.serviceContainer.collectionService, this.serviceContainer.totpService, this.serviceContainer.auditService, this.serviceContainer.keyService, this.serviceContainer.encryptService, this.serviceContainer.searchService, this.serviceContainer.apiService, this.serviceContainer.organizationService, this.serviceContainer.eventCollectionService, this.serviceContainer.billingAccountProfileStateService, this.serviceContainer.accountService, this.serviceContainer.cliRestrictedItemTypesService);
        this.listCommand = new ListCommand(this.serviceContainer.cipherService, this.serviceContainer.folderService, this.serviceContainer.collectionService, this.serviceContainer.organizationService, this.serviceContainer.searchService, this.serviceContainer.organizationUserApiService, this.serviceContainer.apiService, this.serviceContainer.eventCollectionService, this.serviceContainer.accountService, this.serviceContainer.keyService, this.serviceContainer.cliRestrictedItemTypesService, this.serviceContainer.cipherArchiveService);
        this.createCommand = new CreateCommand(this.serviceContainer.cipherService, this.serviceContainer.folderService, this.serviceContainer.keyService, this.serviceContainer.encryptService, this.serviceContainer.apiService, this.serviceContainer.folderApiService, this.serviceContainer.billingAccountProfileStateService, this.serviceContainer.organizationService, this.serviceContainer.accountService, this.serviceContainer.cliRestrictedItemTypesService);
        this.editCommand = new EditCommand(this.serviceContainer.cipherService, this.serviceContainer.folderService, this.serviceContainer.keyService, this.serviceContainer.encryptService, this.serviceContainer.apiService, this.serviceContainer.folderApiService, this.serviceContainer.accountService, this.serviceContainer.cliRestrictedItemTypesService, this.serviceContainer.policyService, this.serviceContainer.billingAccountProfileStateService);
        this.generateCommand = new GenerateCommand(this.serviceContainer.passwordGenerationService, this.serviceContainer.tokenService, this.serviceContainer.accountService);
        this.syncCommand = new SyncCommand(this.serviceContainer.syncService);
        this.statusCommand = new StatusCommand(this.serviceContainer.environmentService, this.serviceContainer.syncService, this.serviceContainer.accountService, this.serviceContainer.authService, this.serviceContainer.userAutoUnlockKeyService);
        this.deleteCommand = new DeleteCommand(this.serviceContainer.cipherService, this.serviceContainer.folderService, this.serviceContainer.apiService, this.serviceContainer.folderApiService, this.serviceContainer.billingAccountProfileStateService, this.serviceContainer.cipherAuthorizationService, this.serviceContainer.accountService, this.serviceContainer.cliRestrictedItemTypesService);
        this.archiveCommand = new ArchiveCommand(this.serviceContainer.cipherService, this.serviceContainer.accountService, this.serviceContainer.cipherArchiveService, this.serviceContainer.billingAccountProfileStateService);
        this.confirmCommand = new ConfirmCommand(this.serviceContainer.apiService, this.serviceContainer.keyService, this.serviceContainer.encryptService, this.serviceContainer.organizationUserApiService, this.serviceContainer.accountService, this.serviceContainer.i18nService);
        this.restoreCommand = new RestoreCommand(this.serviceContainer.cipherService, this.serviceContainer.accountService, this.serviceContainer.cipherAuthorizationService, this.serviceContainer.cipherArchiveService);
        this.shareCommand = new ShareCommand(this.serviceContainer.cipherService, this.serviceContainer.accountService);
        this.lockCommand = new LockCommand(serviceContainer.lockService, serviceContainer.accountService);
        this.unlockCommand = new UnlockCommand(this.serviceContainer.accountService, this.serviceContainer.keyService, this.serviceContainer.cryptoFunctionService, this.serviceContainer.logService, this.serviceContainer.keyConnectorService, this.serviceContainer.environmentService, this.serviceContainer.organizationApiService, () => oss_serve_configurator_awaiter(this, void 0, void 0, function* () { return yield this.serviceContainer.logout(); }), this.serviceContainer.i18nService, this.serviceContainer.encryptedMigrator, this.serviceContainer.masterPasswordUnlockService, this.serviceContainer.unlockService, this.serviceContainer.configService);
        this.sendCreateCommand = new SendCreateCommand(this.serviceContainer.sendService, this.serviceContainer.environmentService, this.serviceContainer.sendApiService, this.serviceContainer.billingAccountProfileStateService, this.serviceContainer.accountService);
        this.sendDeleteCommand = new SendDeleteCommand(this.serviceContainer.sendService, this.serviceContainer.sendApiService);
        this.sendGetCommand = new SendGetCommand(this.serviceContainer.sendService, this.serviceContainer.environmentService, this.serviceContainer.searchService, this.serviceContainer.encryptService, this.serviceContainer.apiService, this.serviceContainer.accountService);
        this.sendEditCommand = new SendEditCommand(this.serviceContainer.sendService, this.sendGetCommand, this.serviceContainer.sendApiService, this.serviceContainer.billingAccountProfileStateService, this.serviceContainer.accountService);
        this.sendListCommand = new SendListCommand(this.serviceContainer.sendService, this.serviceContainer.environmentService, this.serviceContainer.searchService, this.serviceContainer.accountService);
        this.sendRemovePasswordCommand = new SendRemovePasswordCommand(this.serviceContainer.sendService, this.serviceContainer.sendApiService, this.serviceContainer.environmentService, this.serviceContainer.accountService);
    }
    configureRouter(router) {
        return oss_serve_configurator_awaiter(this, void 0, void 0, function* () {
            router.get("/generate", (ctx, next) => oss_serve_configurator_awaiter(this, void 0, void 0, function* () {
                const response = yield this.generateCommand.run(ctx.request.query);
                this.processResponse(ctx.response, response);
                yield next();
            }));
            router.get("/status", (ctx, next) => oss_serve_configurator_awaiter(this, void 0, void 0, function* () {
                const response = yield this.statusCommand.run();
                this.processResponse(ctx.response, response);
                yield next();
            }));
            router.get("/list/object/:object", (ctx, next) => oss_serve_configurator_awaiter(this, void 0, void 0, function* () {
                if (yield this.errorIfLocked(ctx.response)) {
                    yield next();
                    return;
                }
                let response = null;
                if (ctx.params.object === "send") {
                    response = yield this.sendListCommand.run(ctx.request.query);
                }
                else {
                    response = yield this.listCommand.run(ctx.params.object, ctx.request.query);
                }
                this.processResponse(ctx.response, response);
                yield next();
            }));
            router.get("/send/list", (ctx, next) => oss_serve_configurator_awaiter(this, void 0, void 0, function* () {
                if (yield this.errorIfLocked(ctx.response)) {
                    yield next();
                    return;
                }
                const response = yield this.sendListCommand.run(ctx.request.query);
                this.processResponse(ctx.response, response);
                yield next();
            }));
            router.post("/sync", (ctx, next) => oss_serve_configurator_awaiter(this, void 0, void 0, function* () {
                const response = yield this.syncCommand.run(ctx.request.query);
                this.processResponse(ctx.response, response);
                yield next();
            }));
            router.post("/lock", (ctx, next) => oss_serve_configurator_awaiter(this, void 0, void 0, function* () {
                const response = yield this.lockCommand.run();
                this.processResponse(ctx.response, response);
                yield next();
            }));
            router.post("/unlock", (ctx, next) => oss_serve_configurator_awaiter(this, void 0, void 0, function* () {
                // Do not allow guessing password location through serve command
                delete ctx.request.query.passwordFile;
                delete ctx.request.query.passwordEnv;
                const response = yield this.unlockCommand.run(ctx.request.body.password == null ? null : ctx.request.body.password, ctx.request.query);
                this.processResponse(ctx.response, response);
                yield next();
            }));
            router.post("/confirm/:object/:id", (ctx, next) => oss_serve_configurator_awaiter(this, void 0, void 0, function* () {
                if (yield this.errorIfLocked(ctx.response)) {
                    yield next();
                    return;
                }
                const response = yield this.confirmCommand.run(ctx.params.object, ctx.params.id, ctx.request.query);
                this.processResponse(ctx.response, response);
                yield next();
            }));
            router.post("/restore/:object/:id", (ctx, next) => oss_serve_configurator_awaiter(this, void 0, void 0, function* () {
                if (yield this.errorIfLocked(ctx.response)) {
                    yield next();
                    return;
                }
                const response = yield this.restoreCommand.run(ctx.params.object, ctx.params.id);
                this.processResponse(ctx.response, response);
                yield next();
            }));
            router.post("/move/:id/:organizationId", (ctx, next) => oss_serve_configurator_awaiter(this, void 0, void 0, function* () {
                if (yield this.errorIfLocked(ctx.response)) {
                    yield next();
                    return;
                }
                const response = yield this.shareCommand.run(ctx.params.id, ctx.params.organizationId, ctx.request.body);
                this.processResponse(ctx.response, response);
                yield next();
            }));
            router.post("/attachment", multer_namespaceObject().single("file"), (ctx, next) => oss_serve_configurator_awaiter(this, void 0, void 0, function* () {
                if (yield this.errorIfLocked(ctx.response)) {
                    yield next();
                    return;
                }
                const response = yield this.createCommand.run("attachment", ctx.request.body, ctx.request.query, {
                    fileBuffer: ctx.request.file.buffer,
                    fileName: ctx.request.file.originalname,
                });
                this.processResponse(ctx.response, response);
                yield next();
            }));
            router.post("/send/:id/remove-password", (ctx, next) => oss_serve_configurator_awaiter(this, void 0, void 0, function* () {
                if (yield this.errorIfLocked(ctx.response)) {
                    yield next();
                    return;
                }
                const response = yield this.sendRemovePasswordCommand.run(ctx.params.id);
                this.processResponse(ctx.response, response);
                yield next();
            }));
            router.post("/object/:object", (ctx, next) => oss_serve_configurator_awaiter(this, void 0, void 0, function* () {
                if (yield this.errorIfLocked(ctx.response)) {
                    yield next();
                    return;
                }
                let response = null;
                if (ctx.params.object === "send") {
                    response = yield this.sendCreateCommand.run(ctx.request.body, ctx.request.query);
                }
                else {
                    response = yield this.createCommand.run(ctx.params.object, ctx.request.body, ctx.request.query);
                }
                this.processResponse(ctx.response, response);
                yield next();
            }));
            router.put("/object/:object/:id", (ctx, next) => oss_serve_configurator_awaiter(this, void 0, void 0, function* () {
                if (yield this.errorIfLocked(ctx.response)) {
                    yield next();
                    return;
                }
                let response = null;
                if (ctx.params.object === "send") {
                    ctx.request.body.id = ctx.params.id;
                    response = yield this.sendEditCommand.run(ctx.request.body, ctx.request.query);
                }
                else {
                    response = yield this.editCommand.run(ctx.params.object, ctx.params.id, ctx.request.body, ctx.request.query);
                }
                this.processResponse(ctx.response, response);
                yield next();
            }));
            router.get("/object/:object/:id", (ctx, next) => oss_serve_configurator_awaiter(this, void 0, void 0, function* () {
                if (yield this.errorIfLocked(ctx.response)) {
                    yield next();
                    return;
                }
                let response = null;
                if (ctx.params.object === "send") {
                    response = yield this.sendGetCommand.run(ctx.params.id, null);
                }
                else {
                    response = yield this.getCommand.run(ctx.params.object, ctx.params.id, ctx.request.query);
                }
                this.processResponse(ctx.response, response);
                yield next();
            }));
            router.delete("/object/:object/:id", (ctx, next) => oss_serve_configurator_awaiter(this, void 0, void 0, function* () {
                if (yield this.errorIfLocked(ctx.response)) {
                    yield next();
                    return;
                }
                let response = null;
                if (ctx.params.object === "send") {
                    response = yield this.sendDeleteCommand.run(ctx.params.id);
                }
                else {
                    response = yield this.deleteCommand.run(ctx.params.object, ctx.params.id, ctx.request.query);
                }
                this.processResponse(ctx.response, response);
                yield next();
            }));
            router.post("/archive/:object/:id", (ctx, next) => oss_serve_configurator_awaiter(this, void 0, void 0, function* () {
                if (yield this.errorIfLocked(ctx.response)) {
                    yield next();
                    return;
                }
                let response = null;
                response = yield this.archiveCommand.run(ctx.params.object, ctx.params.id);
                this.processResponse(ctx.response, response);
                yield next();
            }));
        });
    }
    processResponse(res, commandResponse) {
        if (!commandResponse.success) {
            res.status = 400;
        }
        if (commandResponse.data instanceof FileResponse) {
            res.body = commandResponse.data.data;
            res.attachment(commandResponse.data.fileName);
            res.set("Content-Type", "application/octet-stream");
            res.set("Content-Length", commandResponse.data.data.length.toString());
        }
        else {
            res.body = commandResponse;
        }
    }
    errorIfLocked(res) {
        return oss_serve_configurator_awaiter(this, void 0, void 0, function* () {
            const userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.serviceContainer.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.map)((account) => account === null || account === void 0 ? void 0 : account.id)));
            const authed = userId != null ||
                (yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.serviceContainer.tokenService.hasAccessToken$(userId)));
            if (!authed) {
                this.processResponse(res, response_Response.error("You are not logged in."));
                return true;
            }
            if (yield this.serviceContainer.keyService.hasUserKey(userId)) {
                return false;
            }
            this.processResponse(res, response_Response.error("Vault is locked."));
            return true;
        });
    }
}

;// ../../bitwarden_license/bit-cli/src/admin-console/device-approval/approve-all.command.ts
var approve_all_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore





class ApproveAllCommand {
    constructor(organizationAuthRequestService, organizationService, accountService) {
        this.organizationAuthRequestService = organizationAuthRequestService;
        this.organizationService = organizationService;
        this.accountService = accountService;
    }
    run(organizationId) {
        return approve_all_command_awaiter(this, void 0, void 0, function* () {
            if (organizationId != null) {
                organizationId = organizationId.toLowerCase();
            }
            if (!utils_Utils.isGuid(organizationId)) {
                return response_Response.badRequest("`" + organizationId + "` is not a GUID.");
            }
            const userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(account_service_getUserId(this.accountService.activeAccount$));
            const organization = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.organizationService
                .organizations$(userId)
                .pipe((0,external_rxjs_namespaceObject.map)((organizations) => organizations.find((o) => o.id === organizationId))));
            if (!(organization === null || organization === void 0 ? void 0 : organization.canManageUsersPassword)) {
                return response_Response.error("You do not have permission to approve pending device authorization requests.");
            }
            try {
                const pendingApprovals = yield this.organizationAuthRequestService.listPendingRequests(organizationId);
                if (pendingApprovals.length == 0) {
                    const res = new MessageResponse("No pending device authorization requests to approve.", null);
                    return response_Response.success(res);
                }
                yield this.organizationAuthRequestService.approvePendingRequests(organizationId, pendingApprovals);
                return response_Response.success();
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
    static create(serviceContainer) {
        return new ApproveAllCommand(serviceContainer.organizationAuthRequestService, serviceContainer.organizationService, serviceContainer.accountService);
    }
}

;// ../../bitwarden_license/bit-cli/src/admin-console/device-approval/approve.command.ts
var approve_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};




class ApproveCommand {
    constructor(organizationService, organizationAuthRequestService, accountService) {
        this.organizationService = organizationService;
        this.organizationAuthRequestService = organizationAuthRequestService;
        this.accountService = accountService;
    }
    run(organizationId, id) {
        return approve_command_awaiter(this, void 0, void 0, function* () {
            if (organizationId != null) {
                organizationId = organizationId.toLowerCase();
            }
            if (!utils_Utils.isGuid(organizationId)) {
                return response_Response.badRequest("`" + organizationId + "` is not a GUID.");
            }
            if (id != null) {
                id = id.toLowerCase();
            }
            if (!utils_Utils.isGuid(id)) {
                return response_Response.badRequest("`" + id + "` is not a GUID.");
            }
            const userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(account_service_getUserId(this.accountService.activeAccount$));
            if (!userId) {
                return response_Response.badRequest("No user found.");
            }
            const organization = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.organizationService
                .organizations$(userId)
                .pipe((0,external_rxjs_namespaceObject.map)((organizations) => organizations === null || organizations === void 0 ? void 0 : organizations.find((o) => o.id === organizationId))));
            if (!(organization === null || organization === void 0 ? void 0 : organization.canManageUsersPassword)) {
                return response_Response.error("You do not have permission to approve pending device authorization requests.");
            }
            try {
                const pendingRequests = yield this.organizationAuthRequestService.listPendingRequests(organizationId);
                const request = pendingRequests.find((r) => r.id == id);
                if (request == null) {
                    return response_Response.error("The request id is invalid.");
                }
                yield this.organizationAuthRequestService.approvePendingRequest(organizationId, request);
                return response_Response.success();
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
    static create(serviceContainer) {
        return new ApproveCommand(serviceContainer.organizationService, serviceContainer.organizationAuthRequestService, serviceContainer.accountService);
    }
}

;// ../../bitwarden_license/bit-cli/src/admin-console/device-approval/deny-all.command.ts
var deny_all_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore





class DenyAllCommand {
    constructor(organizationService, organizationAuthRequestService, accountService) {
        this.organizationService = organizationService;
        this.organizationAuthRequestService = organizationAuthRequestService;
        this.accountService = accountService;
    }
    run(organizationId) {
        return deny_all_command_awaiter(this, void 0, void 0, function* () {
            if (organizationId != null) {
                organizationId = organizationId.toLowerCase();
            }
            if (!utils_Utils.isGuid(organizationId)) {
                return response_Response.badRequest("`" + organizationId + "` is not a GUID.");
            }
            const userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(account_service_getUserId(this.accountService.activeAccount$));
            if (!userId) {
                return response_Response.badRequest("No user found.");
            }
            const organization = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.organizationService
                .organizations$(userId)
                .pipe((0,external_rxjs_namespaceObject.map)((organizations) => organizations.find((o) => o.id === organizationId))));
            if (!(organization === null || organization === void 0 ? void 0 : organization.canManageUsersPassword)) {
                return response_Response.error("You do not have permission to approve pending device authorization requests.");
            }
            try {
                const pendingRequests = yield this.organizationAuthRequestService.listPendingRequests(organizationId);
                if (pendingRequests.length == 0) {
                    const res = new MessageResponse("No pending device authorization requests to deny.", null);
                    return response_Response.success(res);
                }
                yield this.organizationAuthRequestService.denyPendingRequests(organizationId, ...pendingRequests.map((r) => r.id));
                return response_Response.success();
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
    static create(serviceContainer) {
        return new DenyAllCommand(serviceContainer.organizationService, serviceContainer.organizationAuthRequestService, serviceContainer.accountService);
    }
}

;// ../../bitwarden_license/bit-cli/src/admin-console/device-approval/deny.command.ts
var deny_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};



class DenyCommand {
    constructor(organizationService, organizationAuthRequestService, accountServcie) {
        this.organizationService = organizationService;
        this.organizationAuthRequestService = organizationAuthRequestService;
        this.accountServcie = accountServcie;
    }
    run(organizationId, id) {
        return deny_command_awaiter(this, void 0, void 0, function* () {
            if (organizationId != null) {
                organizationId = organizationId.toLowerCase();
            }
            if (!utils_Utils.isGuid(organizationId)) {
                return response_Response.badRequest("`" + organizationId + "` is not a GUID.");
            }
            if (id != null) {
                id = id.toLowerCase();
            }
            if (!utils_Utils.isGuid(id)) {
                return response_Response.badRequest("`" + id + "` is not a GUID.");
            }
            const userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountServcie.activeAccount$.pipe((0,external_rxjs_namespaceObject.map)((a) => a === null || a === void 0 ? void 0 : a.id)));
            if (!userId) {
                return response_Response.badRequest("No user found.");
            }
            const organization = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.organizationService
                .organizations$(userId)
                .pipe((0,external_rxjs_namespaceObject.map)((organizations) => organizations.find((o) => o.id === organizationId))));
            if (!(organization === null || organization === void 0 ? void 0 : organization.canManageUsersPassword)) {
                return response_Response.error("You do not have permission to approve pending device authorization requests.");
            }
            try {
                const pendingRequests = yield this.organizationAuthRequestService.listPendingRequests(organizationId);
                const request = pendingRequests.find((r) => r.id == id);
                if (request == null) {
                    return response_Response.error("The request id is invalid.");
                }
                yield this.organizationAuthRequestService.denyPendingRequest(organizationId, id);
                return response_Response.success();
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
    static create(serviceContainer) {
        return new DenyCommand(serviceContainer.organizationService, serviceContainer.organizationAuthRequestService, serviceContainer.accountService);
    }
}

;// ../../bitwarden_license/bit-cli/src/admin-console/device-approval/pending-auth-request.response.ts
class PendingAuthRequestResponse {
    constructor(authRequest) {
        this.object = "auth-request";
        this.id = authRequest.id;
        this.userId = authRequest.userId;
        this.organizationUserId = authRequest.organizationUserId;
        this.email = authRequest.email;
        this.requestDeviceIdentifier = authRequest.requestDeviceIdentifier;
        this.requestDeviceType = authRequest.requestDeviceType;
        this.requestIpAddress = authRequest.requestIpAddress;
        this.creationDate = authRequest.creationDate;
        this.fingerprintPhrase = authRequest.fingerprintPhrase;
    }
}

;// ../../bitwarden_license/bit-cli/src/admin-console/device-approval/list.command.ts
var device_approval_list_command_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};






class list_command_ListCommand {
    constructor(organizationAuthRequestService, organizationService, accountService) {
        this.organizationAuthRequestService = organizationAuthRequestService;
        this.organizationService = organizationService;
        this.accountService = accountService;
    }
    run(organizationId) {
        return device_approval_list_command_awaiter(this, void 0, void 0, function* () {
            if (organizationId != null) {
                organizationId = organizationId.toLowerCase();
            }
            if (!utils_Utils.isGuid(organizationId)) {
                return response_Response.badRequest("`" + organizationId + "` is not a GUID.");
            }
            const userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(account_service_getUserId(this.accountService.activeAccount$));
            if (!userId) {
                return response_Response.badRequest("No user found.");
            }
            const organization = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.organizationService
                .organizations$(userId)
                .pipe((0,external_rxjs_namespaceObject.map)((organizations) => organizations.find((o) => o.id === organizationId))));
            if (!(organization === null || organization === void 0 ? void 0 : organization.canManageUsersPassword)) {
                return response_Response.error("You do not have permission to approve pending device authorization requests.");
            }
            try {
                const requests = yield this.organizationAuthRequestService.listPendingRequestsWithFingerprint(organizationId);
                const res = new list_response_ListResponse(requests.map((r) => new PendingAuthRequestResponse(r)));
                return response_Response.success(res);
            }
            catch (e) {
                return response_Response.error(e);
            }
        });
    }
    static create(serviceContainer) {
        return new list_command_ListCommand(serviceContainer.organizationAuthRequestService, serviceContainer.organizationService, serviceContainer.accountService);
    }
}

;// ../../bitwarden_license/bit-cli/src/admin-console/device-approval/device-approval.program.ts
var device_approval_program_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};







class DeviceApprovalProgram extends BaseProgram {
    constructor(serviceContainer) {
        super(serviceContainer);
        this.serviceContainer = serviceContainer;
    }
    register() {
        external_commander_namespaceObject.program.addCommand(this.deviceApprovalCommand());
    }
    deviceApprovalCommand() {
        return new external_commander_namespaceObject.Command("device-approval")
            .description("Manage device approval requests sent to organizations that use SSO with trusted devices.")
            .addCommand(this.listCommand())
            .addCommand(this.approveCommand())
            .addCommand(this.approveAllCommand())
            .addCommand(this.denyCommand())
            .addCommand(this.denyAllCommand());
    }
    listCommand() {
        return new external_commander_namespaceObject.Command("list")
            .description("List all pending requests for an organization")
            .requiredOption("--organizationid <organizationid>", "The organization id (required)")
            .action((options) => device_approval_program_awaiter(this, void 0, void 0, function* () {
            yield this.exitIfLocked();
            const cmd = list_command_ListCommand.create(this.serviceContainer);
            const response = yield cmd.run(options.organizationid);
            this.processResponse(response);
        }));
    }
    approveCommand() {
        return new external_commander_namespaceObject.Command("approve")
            .argument("<requestId>", "The id of the request to approve")
            .requiredOption("--organizationid <organizationid>", "The organization id (required)")
            .description("Approve a pending request")
            .action((id, options) => device_approval_program_awaiter(this, void 0, void 0, function* () {
            yield this.exitIfLocked();
            const cmd = ApproveCommand.create(this.serviceContainer);
            const response = yield cmd.run(options.organizationid, id);
            this.processResponse(response);
        }));
    }
    approveAllCommand() {
        return new external_commander_namespaceObject.Command("approve-all")
            .description("Approve all pending requests for an organization")
            .requiredOption("--organizationid <organizationid>", "The organization id (required)")
            .action((options) => device_approval_program_awaiter(this, void 0, void 0, function* () {
            yield this.exitIfLocked();
            const cmd = ApproveAllCommand.create(this.serviceContainer);
            const response = yield cmd.run(options.organizationid);
            this.processResponse(response);
        }));
    }
    denyCommand() {
        return new external_commander_namespaceObject.Command("deny")
            .argument("<requestId>", "The id of the request to deny")
            .requiredOption("--organizationid <organizationid>", "The organization id (required)")
            .description("Deny a pending request")
            .action((id, options) => device_approval_program_awaiter(this, void 0, void 0, function* () {
            yield this.exitIfLocked();
            const cmd = DenyCommand.create(this.serviceContainer);
            const response = yield cmd.run(options.organizationid, id);
            this.processResponse(response);
        }));
    }
    denyAllCommand() {
        return new external_commander_namespaceObject.Command("deny-all")
            .description("Deny all pending requests for an organization")
            .requiredOption("--organizationid <organizationid>", "The organization id (required)")
            .action((options) => device_approval_program_awaiter(this, void 0, void 0, function* () {
            yield this.exitIfLocked();
            const cmd = DenyAllCommand.create(this.serviceContainer);
            const response = yield cmd.run(options.organizationid);
            this.processResponse(response);
        }));
    }
}

;// ../../bitwarden_license/bit-cli/src/admin-console/device-approval/index.ts







;// ../../bitwarden_license/bit-cli/src/bit-serve-configurator.ts
var bit_serve_configurator_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};


class BitServeConfigurator extends OssServeConfigurator {
    constructor(serviceContainer) {
        super(serviceContainer);
        this.serviceContainer = serviceContainer;
    }
    configureRouter(router) {
        const _super = Object.create(null, {
            configureRouter: { get: () => super.configureRouter }
        });
        return bit_serve_configurator_awaiter(this, void 0, void 0, function* () {
            // Register OSS endpoints
            yield _super.configureRouter.call(this, router);
            // Register bit endpoints
            this.serveDeviceApprovals(router);
        });
    }
    serveDeviceApprovals(router) {
        router.get("/device-approval/:organizationId", (ctx, next) => bit_serve_configurator_awaiter(this, void 0, void 0, function* () {
            if (yield this.errorIfLocked(ctx.response)) {
                yield next();
                return;
            }
            const response = yield list_command_ListCommand.create(this.serviceContainer).run(ctx.params.organizationId);
            this.processResponse(ctx.response, response);
            yield next();
        }));
        router.post("/device-approval/:organizationId/approve-all", (ctx, next) => bit_serve_configurator_awaiter(this, void 0, void 0, function* () {
            if (yield this.errorIfLocked(ctx.response)) {
                yield next();
                return;
            }
            const response = yield ApproveAllCommand.create(this.serviceContainer).run(ctx.params.organizationId);
            this.processResponse(ctx.response, response);
            yield next();
        }));
        router.post("/device-approval/:organizationId/approve/:requestId", (ctx, next) => bit_serve_configurator_awaiter(this, void 0, void 0, function* () {
            if (yield this.errorIfLocked(ctx.response)) {
                yield next();
                return;
            }
            const response = yield ApproveCommand.create(this.serviceContainer).run(ctx.params.organizationId, ctx.params.requestId);
            this.processResponse(ctx.response, response);
            yield next();
        }));
        router.post("/device-approval/:organizationId/deny-all", (ctx, next) => bit_serve_configurator_awaiter(this, void 0, void 0, function* () {
            if (yield this.errorIfLocked(ctx.response)) {
                yield next();
                return;
            }
            const response = yield DenyAllCommand.create(this.serviceContainer).run(ctx.params.organizationId);
            this.processResponse(ctx.response, response);
            yield next();
        }));
        router.post("/device-approval/:organizationId/deny/:requestId", (ctx, next) => bit_serve_configurator_awaiter(this, void 0, void 0, function* () {
            if (yield this.errorIfLocked(ctx.response)) {
                yield next();
                return;
            }
            const response = yield DenyCommand.create(this.serviceContainer).run(ctx.params.organizationId, ctx.params.requestId);
            this.processResponse(ctx.response, response);
            yield next();
        }));
    }
}

;// ../../bitwarden_license/bit-cli/src/register-bit-programs.ts
var register_bit_programs_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

/**
 * All Bitwarden-licensed programs should be registered here.
 * @example
 * const myProgram = new myProgram(serviceContainer);
 * myProgram.register();
 * @param serviceContainer A class that instantiates services and makes them available for dependency injection
 */
function registerBitPrograms(serviceContainer) {
    return register_bit_programs_awaiter(this, void 0, void 0, function* () {
        new DeviceApprovalProgram(serviceContainer).register();
    });
}

;// ../../bitwarden_license/bit-common/src/admin-console/auth-requests/pending-organization-auth-request.response.ts

class PendingOrganizationAuthRequestResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.id = this.getResponseProperty("Id");
        this.userId = this.getResponseProperty("UserId");
        this.organizationUserId = this.getResponseProperty("OrganizationUserId");
        this.email = this.getResponseProperty("Email");
        this.publicKey = this.getResponseProperty("PublicKey");
        this.requestDeviceIdentifier = this.getResponseProperty("RequestDeviceIdentifier");
        this.requestDeviceType = this.getResponseProperty("RequestDeviceType");
        this.requestIpAddress = this.getResponseProperty("RequestIpAddress");
        this.requestCountryName = this.getResponseProperty("RequestCountryName");
        this.creationDate = this.getResponseProperty("CreationDate");
    }
}

;// ../../bitwarden_license/bit-common/src/admin-console/auth-requests/organization-auth-request-update.request.ts
class OrganizationAuthRequestUpdateRequest {
    constructor(id, approved, key) {
        this.id = id;
        this.approved = approved;
        this.key = key;
    }
}

;// ../../bitwarden_license/bit-common/src/admin-console/auth-requests/pending-auth-request.view.ts
class PendingAuthRequestView {
    static fromResponse(response) {
        const view = Object.assign(new PendingAuthRequestView(), response);
        view.creationDate = new Date(response.creationDate);
        return view;
    }
}

;// ../../bitwarden_license/bit-common/src/admin-console/auth-requests/pending-auth-request-with-fingerprint.view.ts
var pending_auth_request_with_fingerprint_view_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};


class PendingAuthRequestWithFingerprintView extends PendingAuthRequestView {
    constructor() {
        super(...arguments);
        this.fingerprintPhrase = "";
    }
    static fromView(view, keyService) {
        return pending_auth_request_with_fingerprint_view_awaiter(this, void 0, void 0, function* () {
            var _a;
            const requestWithDetailsView = Object.assign(new PendingAuthRequestWithFingerprintView(), view);
            requestWithDetailsView.fingerprintPhrase = (_a = (yield keyService.getFingerprint(requestWithDetailsView.email, utils_Utils.fromB64ToArray(requestWithDetailsView.publicKey)))) === null || _a === void 0 ? void 0 : _a.join("-");
            return requestWithDetailsView;
        });
    }
}

;// ../../bitwarden_license/bit-common/src/admin-console/auth-requests/organization-auth-request.service.ts
var organization_auth_request_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore






class OrganizationAuthRequestService {
    constructor(organizationAuthRequestApiService, keyService, encryptService, organizationUserApiService, accountService) {
        this.organizationAuthRequestApiService = organizationAuthRequestApiService;
        this.keyService = keyService;
        this.encryptService = encryptService;
        this.organizationUserApiService = organizationUserApiService;
        this.accountService = accountService;
    }
    listPendingRequests(organizationId) {
        return organization_auth_request_service_awaiter(this, void 0, void 0, function* () {
            return yield this.organizationAuthRequestApiService.listPendingRequests(organizationId);
        });
    }
    listPendingRequestsWithFingerprint(organizationId) {
        return organization_auth_request_service_awaiter(this, void 0, void 0, function* () {
            var _a;
            return Promise.all(((_a = (yield this.listPendingRequests(organizationId))) !== null && _a !== void 0 ? _a : []).map((r) => organization_auth_request_service_awaiter(this, void 0, void 0, function* () { return yield PendingAuthRequestWithFingerprintView.fromView(r, this.keyService); })));
        });
    }
    denyPendingRequests(organizationId, ...requestIds) {
        return organization_auth_request_service_awaiter(this, void 0, void 0, function* () {
            yield this.organizationAuthRequestApiService.denyPendingRequests(organizationId, ...requestIds);
        });
    }
    approvePendingRequests(organizationId, authRequests) {
        return organization_auth_request_service_awaiter(this, void 0, void 0, function* () {
            const organizationUserIds = authRequests.map((r) => r.organizationUserId);
            const details = yield this.organizationUserApiService.getManyOrganizationUserAccountRecoveryDetails(organizationId, organizationUserIds);
            if (details == null ||
                details.data.length == 0 ||
                details.data.some((d) => d.resetPasswordKey == null)) {
                throw new Error("All users must be enrolled in account recovery (password reset) in order for the requests to be approved.");
            }
            const requestsToApprove = yield Promise.all(authRequests.map((r) => organization_auth_request_service_awaiter(this, void 0, void 0, function* () {
                const detail = details.data.find((d) => d.organizationUserId === r.organizationUserId);
                const encryptedKey = yield this.getEncryptedUserKey(organizationId, r.publicKey, detail);
                return new OrganizationAuthRequestUpdateRequest(r.id, true, encryptedKey.encryptedString);
            })));
            yield this.organizationAuthRequestApiService.bulkUpdatePendingRequests(organizationId, requestsToApprove);
        });
    }
    approvePendingRequest(organizationId, authRequest) {
        return organization_auth_request_service_awaiter(this, void 0, void 0, function* () {
            const details = yield this.organizationUserApiService.getOrganizationUserResetPasswordDetails(organizationId, authRequest.organizationUserId);
            if (details == null || details.resetPasswordKey == null) {
                throw new Error("The user must be enrolled in account recovery (password reset) in order for the request to be approved.");
            }
            const encryptedKey = yield this.getEncryptedUserKey(organizationId, authRequest.publicKey, details);
            yield this.organizationAuthRequestApiService.approvePendingRequest(organizationId, authRequest.id, encryptedKey);
        });
    }
    denyPendingRequest(organizationId, requestId) {
        return organization_auth_request_service_awaiter(this, void 0, void 0, function* () {
            yield this.organizationAuthRequestApiService.denyPendingRequest(organizationId, requestId);
        });
    }
    /**
     * Creates a copy of the user key that has been encrypted with the provided device's public key.
     * @param organizationId
     * @param devicePublicKey
     * @param resetPasswordDetails
     * @private
     */
    getEncryptedUserKey(organizationId, devicePublicKey, resetPasswordDetails) {
        return organization_auth_request_service_awaiter(this, void 0, void 0, function* () {
            const encryptedUserKey = resetPasswordDetails.resetPasswordKey;
            const encryptedOrgPrivateKey = resetPasswordDetails.encryptedPrivateKey;
            const devicePubKey = utils_Utils.fromB64ToArray(devicePublicKey);
            // Decrypt Organization's encrypted Private Key with org key
            const orgSymKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId, (0,external_rxjs_namespaceObject.switchMap)((userId) => this.keyService.orgKeys$(userId)), (0,external_rxjs_namespaceObject.map)((orgKeys) => { var _a; return (_a = orgKeys[organizationId]) !== null && _a !== void 0 ? _a : null; })));
            const decOrgPrivateKey = yield this.encryptService.decryptBytes(new enc_string_EncString(encryptedOrgPrivateKey), orgSymKey);
            // Decrypt user key with decrypted org private key
            const userKey = yield this.encryptService.decapsulateKeyUnsigned(new enc_string_EncString(encryptedUserKey), decOrgPrivateKey);
            // Re-encrypt user Key with the Device Public Key
            return yield this.encryptService.encapsulateKeyUnsigned(userKey, devicePubKey);
        });
    }
}

;// ../../bitwarden_license/bit-common/src/admin-console/auth-requests/admin-auth-request-update.request.ts
class AdminAuthRequestUpdateRequest {
    /**
     *
     * @param requestApproved - Whether the request was approved/denied. If true, the key must be provided.
     * @param encryptedUserKey The user key that has been encrypted with a device public key if the request was approved.
     */
    constructor(requestApproved, encryptedUserKey) {
        this.requestApproved = requestApproved;
        this.encryptedUserKey = encryptedUserKey;
    }
}

;// ../../bitwarden_license/bit-common/src/admin-console/auth-requests/bulk-deny-auth-requests.request.ts
class BulkDenyAuthRequestsRequest {
    constructor(authRequestIds) {
        this.ids = authRequestIds;
    }
}

;// ../../bitwarden_license/bit-common/src/admin-console/auth-requests/organization-auth-request-api.service.ts
var organization_auth_request_api_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};





class OrganizationAuthRequestApiService {
    constructor(apiService) {
        this.apiService = apiService;
    }
    listPendingRequests(organizationId) {
        return organization_auth_request_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("GET", `/organizations/${organizationId}/auth-requests`, null, true, true);
            const listResponse = new ListResponse(r, PendingOrganizationAuthRequestResponse);
            return listResponse.data.map((ar) => PendingAuthRequestView.fromResponse(ar));
        });
    }
    denyPendingRequests(organizationId, ...requestIds) {
        return organization_auth_request_api_service_awaiter(this, void 0, void 0, function* () {
            yield this.apiService.send("POST", `/organizations/${organizationId}/auth-requests/deny`, new BulkDenyAuthRequestsRequest(requestIds), true, false);
        });
    }
    bulkUpdatePendingRequests(organizationId, items) {
        return organization_auth_request_api_service_awaiter(this, void 0, void 0, function* () {
            yield this.apiService.send("POST", `/organizations/${organizationId}/auth-requests`, items, true, false);
        });
    }
    approvePendingRequest(organizationId, requestId, encryptedKey) {
        return organization_auth_request_api_service_awaiter(this, void 0, void 0, function* () {
            yield this.apiService.send("POST", `/organizations/${organizationId}/auth-requests/${requestId}`, new AdminAuthRequestUpdateRequest(true, encryptedKey.encryptedString), true, false);
        });
    }
    denyPendingRequest(organizationId, requestId) {
        return organization_auth_request_api_service_awaiter(this, void 0, void 0, function* () {
            yield this.apiService.send("POST", `/organizations/${organizationId}/auth-requests/${requestId}`, new AdminAuthRequestUpdateRequest(false), true, false);
        });
    }
}

;// ../../bitwarden_license/bit-common/src/admin-console/auth-requests/index.ts





;// external "jsdom"
const external_jsdom_namespaceObject = require("jsdom");
;// ../../libs/common/src/auth/enums/sso.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var SsoType;
(function (SsoType) {
    SsoType[SsoType["None"] = 0] = "None";
    SsoType[SsoType["OpenIdConnect"] = 1] = "OpenIdConnect";
    SsoType[SsoType["Saml2"] = 2] = "Saml2";
})(SsoType || (SsoType = {}));
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var MemberDecryptionType;
(function (MemberDecryptionType) {
    MemberDecryptionType[MemberDecryptionType["MasterPassword"] = 0] = "MasterPassword";
    MemberDecryptionType[MemberDecryptionType["KeyConnector"] = 1] = "KeyConnector";
    MemberDecryptionType[MemberDecryptionType["TrustedDeviceEncryption"] = 2] = "TrustedDeviceEncryption";
})(MemberDecryptionType || (MemberDecryptionType = {}));
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var OpenIdConnectRedirectBehavior;
(function (OpenIdConnectRedirectBehavior) {
    OpenIdConnectRedirectBehavior[OpenIdConnectRedirectBehavior["RedirectGet"] = 0] = "RedirectGet";
    OpenIdConnectRedirectBehavior[OpenIdConnectRedirectBehavior["FormPost"] = 1] = "FormPost";
})(OpenIdConnectRedirectBehavior || (OpenIdConnectRedirectBehavior = {}));
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var Saml2BindingType;
(function (Saml2BindingType) {
    Saml2BindingType[Saml2BindingType["HttpRedirect"] = 1] = "HttpRedirect";
    Saml2BindingType[Saml2BindingType["HttpPost"] = 2] = "HttpPost";
})(Saml2BindingType || (Saml2BindingType = {}));
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var Saml2NameIdFormat;
(function (Saml2NameIdFormat) {
    Saml2NameIdFormat[Saml2NameIdFormat["NotConfigured"] = 0] = "NotConfigured";
    Saml2NameIdFormat[Saml2NameIdFormat["Unspecified"] = 1] = "Unspecified";
    Saml2NameIdFormat[Saml2NameIdFormat["EmailAddress"] = 2] = "EmailAddress";
    Saml2NameIdFormat[Saml2NameIdFormat["X509SubjectName"] = 3] = "X509SubjectName";
    Saml2NameIdFormat[Saml2NameIdFormat["WindowsDomainQualifiedName"] = 4] = "WindowsDomainQualifiedName";
    Saml2NameIdFormat[Saml2NameIdFormat["KerberosPrincipalName"] = 5] = "KerberosPrincipalName";
    Saml2NameIdFormat[Saml2NameIdFormat["EntityIdentifier"] = 6] = "EntityIdentifier";
    Saml2NameIdFormat[Saml2NameIdFormat["Persistent"] = 7] = "Persistent";
    Saml2NameIdFormat[Saml2NameIdFormat["Transient"] = 8] = "Transient";
})(Saml2NameIdFormat || (Saml2NameIdFormat = {}));
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var Saml2SigningBehavior;
(function (Saml2SigningBehavior) {
    Saml2SigningBehavior[Saml2SigningBehavior["IfIdpWantAuthnRequestsSigned"] = 0] = "IfIdpWantAuthnRequestsSigned";
    Saml2SigningBehavior[Saml2SigningBehavior["Always"] = 1] = "Always";
    Saml2SigningBehavior[Saml2SigningBehavior["Never"] = 3] = "Never";
})(Saml2SigningBehavior || (Saml2SigningBehavior = {}));

;// ../../libs/common/src/billing/enums/discount-tier-type.enum.ts
const DiscountTierType = Object.freeze({
    Premium: "Premium",
    Families: "Families",
});

;// ../../libs/common/src/billing/enums/payment-method-type.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var PaymentMethodType;
(function (PaymentMethodType) {
    PaymentMethodType[PaymentMethodType["Card"] = 0] = "Card";
    PaymentMethodType[PaymentMethodType["BankAccount"] = 1] = "BankAccount";
    PaymentMethodType[PaymentMethodType["PayPal"] = 2] = "PayPal";
    PaymentMethodType[PaymentMethodType["BitPay"] = 3] = "BitPay";
    PaymentMethodType[PaymentMethodType["Credit"] = 4] = "Credit";
    PaymentMethodType[PaymentMethodType["WireTransfer"] = 5] = "WireTransfer";
    PaymentMethodType[PaymentMethodType["Check"] = 8] = "Check";
})(PaymentMethodType || (PaymentMethodType = {}));

;// ../../libs/common/src/billing/enums/plan-sponsorship-type.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var PlanSponsorshipType;
(function (PlanSponsorshipType) {
    PlanSponsorshipType[PlanSponsorshipType["FamiliesForEnterprise"] = 0] = "FamiliesForEnterprise";
})(PlanSponsorshipType || (PlanSponsorshipType = {}));

;// ../../libs/common/src/billing/enums/plan-type.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var PlanType;
(function (PlanType) {
    PlanType[PlanType["Free"] = 0] = "Free";
    PlanType[PlanType["FamiliesAnnually2019"] = 1] = "FamiliesAnnually2019";
    PlanType[PlanType["TeamsMonthly2019"] = 2] = "TeamsMonthly2019";
    PlanType[PlanType["TeamsAnnually2019"] = 3] = "TeamsAnnually2019";
    PlanType[PlanType["EnterpriseMonthly2019"] = 4] = "EnterpriseMonthly2019";
    PlanType[PlanType["EnterpriseAnnually2019"] = 5] = "EnterpriseAnnually2019";
    PlanType[PlanType["Custom"] = 6] = "Custom";
    PlanType[PlanType["FamiliesAnnually2025"] = 7] = "FamiliesAnnually2025";
    PlanType[PlanType["TeamsMonthly2020"] = 8] = "TeamsMonthly2020";
    PlanType[PlanType["TeamsAnnually2020"] = 9] = "TeamsAnnually2020";
    PlanType[PlanType["EnterpriseMonthly2020"] = 10] = "EnterpriseMonthly2020";
    PlanType[PlanType["EnterpriseAnnually2020"] = 11] = "EnterpriseAnnually2020";
    PlanType[PlanType["TeamsMonthly2023"] = 12] = "TeamsMonthly2023";
    PlanType[PlanType["TeamsAnnually2023"] = 13] = "TeamsAnnually2023";
    PlanType[PlanType["EnterpriseMonthly2023"] = 14] = "EnterpriseMonthly2023";
    PlanType[PlanType["EnterpriseAnnually2023"] = 15] = "EnterpriseAnnually2023";
    PlanType[PlanType["TeamsStarter2023"] = 16] = "TeamsStarter2023";
    PlanType[PlanType["TeamsMonthly"] = 17] = "TeamsMonthly";
    PlanType[PlanType["TeamsAnnually"] = 18] = "TeamsAnnually";
    PlanType[PlanType["EnterpriseMonthly"] = 19] = "EnterpriseMonthly";
    PlanType[PlanType["EnterpriseAnnually"] = 20] = "EnterpriseAnnually";
    PlanType[PlanType["TeamsStarter"] = 21] = "TeamsStarter";
    PlanType[PlanType["FamiliesAnnually"] = 22] = "FamiliesAnnually";
})(PlanType || (PlanType = {}));

;// ../../libs/common/src/billing/enums/transaction-type.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var TransactionType;
(function (TransactionType) {
    TransactionType[TransactionType["Charge"] = 0] = "Charge";
    TransactionType[TransactionType["Credit"] = 1] = "Credit";
    TransactionType[TransactionType["PromotionalCredit"] = 2] = "PromotionalCredit";
    TransactionType[TransactionType["ReferralCredit"] = 3] = "ReferralCredit";
    TransactionType[TransactionType["Refund"] = 4] = "Refund";
})(TransactionType || (TransactionType = {}));

;// ../../libs/common/src/billing/enums/product-tier-type.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var ProductTierType;
(function (ProductTierType) {
    ProductTierType[ProductTierType["Free"] = 0] = "Free";
    ProductTierType[ProductTierType["Families"] = 1] = "Families";
    ProductTierType[ProductTierType["Teams"] = 2] = "Teams";
    ProductTierType[ProductTierType["Enterprise"] = 3] = "Enterprise";
    ProductTierType[ProductTierType["TeamsStarter"] = 4] = "TeamsStarter";
})(ProductTierType || (ProductTierType = {}));
function isNotSelfUpgradable(productType) {
    return (productType !== ProductTierType.Free &&
        productType !== ProductTierType.TeamsStarter &&
        productType !== ProductTierType.Families);
}

;// ../../libs/common/src/billing/enums/product-type.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var product_type_enum_ProductType;
(function (ProductType) {
    ProductType[ProductType["PasswordManager"] = 0] = "PasswordManager";
    ProductType[ProductType["SecretsManager"] = 1] = "SecretsManager";
})(product_type_enum_ProductType || (product_type_enum_ProductType = {}));

;// ../../libs/common/src/billing/enums/plan-interval.enum.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var PlanInterval;
(function (PlanInterval) {
    PlanInterval[PlanInterval["Monthly"] = 0] = "Monthly";
    PlanInterval[PlanInterval["Annually"] = 1] = "Annually";
})(PlanInterval || (PlanInterval = {}));

;// ../../libs/common/src/billing/enums/index.ts









;// ../../libs/common/src/admin-console/models/domain/organization.ts



class Organization {
    constructor(obj) {
        var _a;
        if (obj == null) {
            return;
        }
        this.id = obj.id;
        this.name = obj.name;
        this.status = obj.status;
        this.type = obj.type;
        this.enabled = obj.enabled;
        this.usePolicies = obj.usePolicies;
        this.useGroups = obj.useGroups;
        this.useDirectory = obj.useDirectory;
        this.useEvents = obj.useEvents;
        this.useTotp = obj.useTotp;
        this.use2fa = obj.use2fa;
        this.useApi = obj.useApi;
        this.useSso = obj.useSso;
        this.useOrganizationDomains = obj.useOrganizationDomains;
        this.useKeyConnector = obj.useKeyConnector;
        this.useScim = obj.useScim;
        this.useCustomPermissions = obj.useCustomPermissions;
        this.useResetPassword = obj.useResetPassword;
        this.useSecretsManager = obj.useSecretsManager;
        this.usePasswordManager = obj.usePasswordManager;
        this.useActivateAutofillPolicy = obj.useActivateAutofillPolicy;
        this.useAutomaticUserConfirmation = obj.useAutomaticUserConfirmation;
        this.selfHost = obj.selfHost;
        this.usersGetPremium = obj.usersGetPremium;
        this.seats = obj.seats;
        this.maxCollections = obj.maxCollections;
        this.maxStorageGb = obj.maxStorageGb;
        this.ssoBound = obj.ssoBound;
        this.identifier = obj.identifier;
        this.permissions = obj.permissions;
        this.resetPasswordEnrolled = obj.resetPasswordEnrolled;
        this.userId = obj.userId;
        this.organizationUserId = obj.organizationUserId;
        this.hasPublicAndPrivateKeys = obj.hasPublicAndPrivateKeys;
        this.providerId = obj.providerId;
        this.providerName = obj.providerName;
        this.providerType = obj.providerType;
        this.isProviderUser = obj.isProviderUser;
        this.isMember = obj.isMember;
        this.familySponsorshipFriendlyName = obj.familySponsorshipFriendlyName;
        this.familySponsorshipAvailable = obj.familySponsorshipAvailable;
        this.productTierType = obj.productTierType;
        this.keyConnectorEnabled = obj.keyConnectorEnabled;
        this.keyConnectorUrl = obj.keyConnectorUrl;
        this.familySponsorshipLastSyncDate = obj.familySponsorshipLastSyncDate;
        this.familySponsorshipValidUntil = obj.familySponsorshipValidUntil;
        this.familySponsorshipToDelete = obj.familySponsorshipToDelete;
        this.accessSecretsManager = obj.accessSecretsManager;
        this.limitCollectionCreation = obj.limitCollectionCreation;
        this.limitCollectionDeletion = obj.limitCollectionDeletion;
        this.limitItemDeletion = obj.limitItemDeletion;
        this.allowAdminAccessToAllCollectionItems = obj.allowAdminAccessToAllCollectionItems;
        this.userIsManagedByOrganization = obj.userIsManagedByOrganization;
        this.useAccessIntelligence = obj.useAccessIntelligence;
        this.useAdminSponsoredFamilies = obj.useAdminSponsoredFamilies;
        this.useDisableSMAdsForUsers = (_a = obj.useDisableSMAdsForUsers) !== null && _a !== void 0 ? _a : false;
        this.isAdminInitiated = obj.isAdminInitiated;
        this.ssoEnabled = obj.ssoEnabled;
        this.ssoMemberDecryptionType = obj.ssoMemberDecryptionType;
        this.usePhishingBlocker = obj.usePhishingBlocker;
        this.useMyItems = obj.useMyItems;
    }
    get canAccess() {
        if (this.isOwner) {
            return true;
        }
        return this.enabled && this.status === organization_user_status_type_enum_OrganizationUserStatusType.Confirmed;
    }
    /**
     * Whether a user has Admin permissions or greater
     */
    get isAdmin() {
        return this.type === organization_user_type_enum_OrganizationUserType.Admin || this.isOwner;
    }
    /**
     * Whether a user has Owner permissions (including ProviderUsers)
     */
    get isOwner() {
        return this.type === organization_user_type_enum_OrganizationUserType.Owner || this.isProviderUser;
    }
    get canAccessEventLogs() {
        return (this.isAdmin || this.permissions.accessEventLogs) && this.useEvents;
    }
    /**
     * Returns true if the user can access the Import page in the Admin Console.
     * Note: this does not affect user access to the Import page in Password Manager, which can also be used to import
     * into organization collections.
     */
    get canAccessImport() {
        return (this.isProviderUser ||
            this.type === organization_user_type_enum_OrganizationUserType.Owner ||
            this.type === organization_user_type_enum_OrganizationUserType.Admin ||
            this.permissions.accessImportExport);
    }
    get canAccessExport() {
        return (this.isMember &&
            (this.type === organization_user_type_enum_OrganizationUserType.Owner ||
                this.type === organization_user_type_enum_OrganizationUserType.Admin ||
                this.permissions.accessImportExport));
    }
    get canAccessReports() {
        return this.isAdmin || this.permissions.accessReports;
    }
    get canCreateNewCollections() {
        return !this.limitCollectionCreation || this.isAdmin || this.permissions.createNewCollections;
    }
    get canEditAnyCollection() {
        // The allowAdminAccessToAllCollectionItems flag can restrict admins
        // Providers and custom users with canEditAnyCollection are not affected by allowAdminAccessToAllCollectionItems flag
        return (this.isProviderUser ||
            (this.type === organization_user_type_enum_OrganizationUserType.Custom && this.permissions.editAnyCollection) ||
            (this.allowAdminAccessToAllCollectionItems && this.isAdmin));
    }
    get canEditUnmanagedCollections() {
        // Any admin or custom user with editAnyCollection permission can edit unmanaged collections
        return this.isAdmin || this.permissions.editAnyCollection;
    }
    get canEditUnassignedCiphers() {
        return (this.type === organization_user_type_enum_OrganizationUserType.Admin ||
            this.type === organization_user_type_enum_OrganizationUserType.Owner ||
            this.permissions.editAnyCollection);
    }
    get canEditAllCiphers() {
        // The allowAdminAccessToAllCollectionItems flag can restrict admins
        // Custom users with canEditAnyCollection are not affected by allowAdminAccessToAllCollectionItems flag
        return ((this.type === organization_user_type_enum_OrganizationUserType.Custom && this.permissions.editAnyCollection) ||
            (this.allowAdminAccessToAllCollectionItems &&
                (this.type === organization_user_type_enum_OrganizationUserType.Admin || this.type === organization_user_type_enum_OrganizationUserType.Owner)));
    }
    /**
     * @returns True if the user can delete any collection
     */
    get canDeleteAnyCollection() {
        // Providers and Users with DeleteAnyCollection permission can always delete collections
        if (this.isProviderUser || this.permissions.deleteAnyCollection) {
            return true;
        }
        // If AllowAdminAccessToAllCollectionItems is true, Owners and Admins can delete any collection, regardless of LimitCollectionDeletion setting
        // Using explicit type checks because provider users are handled above and this mimics the server's permission checks closely
        if (this.allowAdminAccessToAllCollectionItems) {
            return this.type == organization_user_type_enum_OrganizationUserType.Owner || this.type == organization_user_type_enum_OrganizationUserType.Admin;
        }
        return false;
    }
    /**
     * Whether the user can view all collection information, such as collection name and access.
     * This does not indicate that the user can view items inside any collection - for that, see {@link canEditAllCiphers}
     */
    get canViewAllCollections() {
        // Admins can always see all collections even if collection management settings prevent them from editing them or seeing items
        return (this.isAdmin || this.permissions.editAnyCollection || this.permissions.deleteAnyCollection);
    }
    get canManageGroups() {
        return (this.isAdmin || this.permissions.manageGroups) && this.useGroups;
    }
    get canManageSso() {
        return (this.isAdmin || this.permissions.manageSso) && this.useSso;
    }
    get canManageDomainVerification() {
        return (this.isAdmin || this.permissions.manageSso) && this.useOrganizationDomains;
    }
    get canManageScim() {
        return (this.isAdmin || this.permissions.manageScim) && this.useScim;
    }
    get canManagePolicies() {
        return (this.isAdmin || this.permissions.managePolicies) && this.usePolicies;
    }
    get canManageUsers() {
        return this.isAdmin || this.permissions.manageUsers;
    }
    get canManageUsersPassword() {
        return this.isAdmin || this.permissions.manageResetPassword;
    }
    get canEnableAutoConfirmPolicy() {
        return ((this.canManageUsers || this.canManagePolicies) &&
            this.useAutomaticUserConfirmation &&
            !this.isProviderUser);
    }
    get canManageDeviceApprovals() {
        return ((this.isAdmin || this.permissions.manageResetPassword) &&
            this.useSso &&
            this.ssoEnabled &&
            this.ssoMemberDecryptionType === MemberDecryptionType.TrustedDeviceEncryption);
    }
    get isExemptFromPolicies() {
        return this.canManagePolicies;
    }
    get canViewSubscription() {
        if (this.canEditSubscription) {
            return true;
        }
        return this.hasBillableProvider ? this.isProviderUser : this.isOwner;
    }
    get canEditSubscription() {
        return this.hasProvider ? this.isProviderUser : this.isOwner;
    }
    get canEditPaymentMethods() {
        return this.canEditSubscription;
    }
    get canViewBillingHistory() {
        return this.canEditSubscription;
    }
    get hasProvider() {
        return this.providerId != null || this.providerName != null;
    }
    get hasBillableProvider() {
        return (this.hasProvider &&
            (this.providerType === provider_type_enum_ProviderType.Msp || this.providerType === provider_type_enum_ProviderType.BusinessUnit));
    }
    get hasReseller() {
        return this.hasProvider && this.providerType === provider_type_enum_ProviderType.Reseller;
    }
    get canAccessSecretsManager() {
        return this.useSecretsManager && this.accessSecretsManager;
    }
    get isFreeOrg() {
        // return true if organization needs to be upgraded from a free org
        return !this.useTotp;
    }
    get canManageSponsorships() {
        return this.familySponsorshipAvailable || this.familySponsorshipFriendlyName !== null;
    }
    /**
     * Do not call this function to perform business logic, use the function in @link AutomaticUserConfirmationService instead.
     **/
    get canManageAutoConfirm() {
        return this.isMember && this.canManageUsers && this.useAutomaticUserConfirmation;
    }
    static fromJSON(json) {
        if (json == null) {
            return null;
        }
        return Object.assign(new Organization(), json, {
            familySponsorshipLastSyncDate: new Date(json.familySponsorshipLastSyncDate),
            familySponsorshipValidUntil: new Date(json.familySponsorshipValidUntil),
        });
    }
    get canAccessIntegrations() {
        return ((this.productTierType === ProductTierType.Teams ||
            this.productTierType === ProductTierType.Enterprise) &&
            (this.isAdmin ||
                this.permissions.manageUsers ||
                this.permissions.manageGroups ||
                this.permissions.accessEventLogs));
    }
    get canUseAccessIntelligence() {
        return this.productTierType === ProductTierType.Enterprise;
    }
}

;// ../../libs/common/src/admin-console/models/data/organization.data.ts
class OrganizationData {
    constructor(response, options) {
        var _a;
        if (response == null) {
            return;
        }
        this.id = response.id;
        this.name = response.name;
        this.status = response.status;
        this.type = response.type;
        this.enabled = response.enabled;
        this.usePolicies = response.usePolicies;
        this.useGroups = response.useGroups;
        this.useDirectory = response.useDirectory;
        this.useEvents = response.useEvents;
        this.useTotp = response.useTotp;
        this.use2fa = response.use2fa;
        this.useApi = response.useApi;
        this.useSso = response.useSso;
        this.useOrganizationDomains = response.useOrganizationDomains;
        this.useKeyConnector = response.useKeyConnector;
        this.useScim = response.useScim;
        this.useCustomPermissions = response.useCustomPermissions;
        this.useResetPassword = response.useResetPassword;
        this.useSecretsManager = response.useSecretsManager;
        this.usePasswordManager = response.usePasswordManager;
        this.useActivateAutofillPolicy = response.useActivateAutofillPolicy;
        this.useAutomaticUserConfirmation = response.useAutomaticUserConfirmation;
        this.selfHost = response.selfHost;
        this.usersGetPremium = response.usersGetPremium;
        this.seats = response.seats;
        this.maxCollections = response.maxCollections;
        this.maxStorageGb = response.maxStorageGb;
        this.ssoBound = response.ssoBound;
        this.identifier = response.identifier;
        this.permissions = response.permissions;
        this.resetPasswordEnrolled = response.resetPasswordEnrolled;
        this.userId = response.userId;
        this.organizationUserId = response.organizationUserId;
        this.hasPublicAndPrivateKeys = response.hasPublicAndPrivateKeys;
        this.providerId = response.providerId;
        this.providerName = response.providerName;
        this.providerType = response.providerType;
        this.familySponsorshipFriendlyName = response.familySponsorshipFriendlyName;
        this.familySponsorshipAvailable = response.familySponsorshipAvailable;
        this.productTierType = response.productTierType;
        this.keyConnectorEnabled = response.keyConnectorEnabled;
        this.keyConnectorUrl = response.keyConnectorUrl;
        this.familySponsorshipLastSyncDate = response.familySponsorshipLastSyncDate;
        this.familySponsorshipValidUntil = response.familySponsorshipValidUntil;
        this.familySponsorshipToDelete = response.familySponsorshipToDelete;
        this.accessSecretsManager = response.accessSecretsManager;
        this.limitCollectionCreation = response.limitCollectionCreation;
        this.limitCollectionDeletion = response.limitCollectionDeletion;
        this.limitItemDeletion = response.limitItemDeletion;
        this.allowAdminAccessToAllCollectionItems = response.allowAdminAccessToAllCollectionItems;
        this.userIsManagedByOrganization = response.userIsManagedByOrganization;
        this.useAccessIntelligence = response.useAccessIntelligence;
        this.useAdminSponsoredFamilies = response.useAdminSponsoredFamilies;
        this.useDisableSMAdsForUsers = (_a = response.useDisableSMAdsForUsers) !== null && _a !== void 0 ? _a : false;
        this.isAdminInitiated = response.isAdminInitiated;
        this.ssoEnabled = response.ssoEnabled;
        this.ssoMemberDecryptionType = response.ssoMemberDecryptionType;
        this.usePhishingBlocker = response.usePhishingBlocker;
        this.useMyItems = response.useMyItems;
        this.isMember = options.isMember;
        this.isProviderUser = options.isProviderUser;
    }
    static fromJSON(obj) {
        return Object.assign(new OrganizationData(), obj, {
            familySponsorshipLastSyncDate: obj.familySponsorshipLastSyncDate != null
                ? new Date(obj.familySponsorshipLastSyncDate)
                : obj.familySponsorshipLastSyncDate,
            familySponsorshipValidUntil: obj.familySponsorshipValidUntil != null
                ? new Date(obj.familySponsorshipValidUntil)
                : obj.familySponsorshipValidUntil,
        });
    }
}

;// ../../libs/common/src/admin-console/services/organization/organization.state.ts


/**
 * The `KeyDefinition` for accessing organization lists in application state.
 * @todo Ideally this wouldn't require a `fromJSON()` call, but `OrganizationData`
 * has some properties that contain functions. This should probably get
 * cleaned up.
 */
const ORGANIZATIONS = UserKeyDefinition.record(ORGANIZATIONS_DISK, "organizations", {
    deserializer: (obj) => OrganizationData.fromJSON(obj),
    clearOn: ["logout"],
});

;// ../../libs/common/src/admin-console/services/organization/default-organization.service.ts
var default_organization_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore



/**
 * Filter out organizations from an observable that __do not__ offer a
 * families-for-enterprise sponsorship to members.
 * @returns a function that can be used in `Observable<Organization[]>` pipes,
 * like `organizationService.organizations$`
 */
function mapToExcludeOrganizationsWithoutFamilySponsorshipSupport() {
    return (0,external_rxjs_namespaceObject.map)((orgs) => orgs.filter((o) => o.canManageSponsorships));
}
/**
 * Filter out organizations from an observable that the organization user
 * __is not__ a direct member of. This will exclude organizations only
 * accessible as a provider.
 * @returns a function that can be used in `Observable<Organization[]>` pipes,
 * like `organizationService.organizations$`
 */
function mapToExcludeProviderOrganizations() {
    return (0,external_rxjs_namespaceObject.map)((orgs) => orgs.filter((o) => o.isMember));
}
/**
 * Map an observable stream of organizations down to a boolean indicating
 * if any organizations exist (`orgs.length > 0`).
 * @returns a function that can be used in `Observable<Organization[]>` pipes,
 * like `organizationService.organizations$`
 */
function mapToBooleanHasAnyOrganizations() {
    return (0,external_rxjs_namespaceObject.map)((orgs) => orgs.length > 0);
}
class DefaultOrganizationService {
    memberOrganizations$(userId) {
        return this.organizations$(userId).pipe(mapToExcludeProviderOrganizations());
    }
    constructor(stateProvider) {
        this.stateProvider = stateProvider;
    }
    canManageSponsorships$(userId) {
        return this.organizations$(userId).pipe(mapToExcludeOrganizationsWithoutFamilySponsorshipSupport(), mapToBooleanHasAnyOrganizations());
    }
    familySponsorshipAvailable$(userId) {
        return this.organizations$(userId).pipe((0,external_rxjs_namespaceObject.map)((orgs) => orgs.some((o) => o.familySponsorshipAvailable)));
    }
    hasOrganizations(userId) {
        return this.organizations$(userId).pipe(mapToBooleanHasAnyOrganizations());
    }
    upsert(organization, userId) {
        return default_organization_service_awaiter(this, void 0, void 0, function* () {
            yield this.organizationState(userId).update((existingOrganizations) => {
                const organizations = existingOrganizations !== null && existingOrganizations !== void 0 ? existingOrganizations : {};
                organizations[organization.id] = organization;
                return organizations;
            });
        });
    }
    replace(organizations, userId) {
        return default_organization_service_awaiter(this, void 0, void 0, function* () {
            yield this.organizationState(userId).update(() => organizations);
        });
    }
    organizations$(userId) {
        return this.organizationState(userId).state$.pipe(this.mapOrganizationRecordToArray());
    }
    organizationState(userId) {
        return this.stateProvider.getUser(userId, ORGANIZATIONS);
    }
    /**
     * Accepts a record of `OrganizationData`, which is how we store the
     * organization list as a JSON object on disk, to an array of
     * `Organization`, which is how the data is published to callers of the
     * service.
     * @returns a function that can be used to pipe organization data from
     * stored state to an exposed object easily consumable by others.
     */
    mapOrganizationRecordToArray() {
        return (0,external_rxjs_namespaceObject.map)((orgs) => { var _a; return (_a = Object.values(orgs !== null && orgs !== void 0 ? orgs : {})) === null || _a === void 0 ? void 0 : _a.map((o) => new Organization(o)); });
    }
}

;// ../../libs/common/src/auth/models/response/api-key.response.ts

class ApiKeyResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.apiKey = this.getResponseProperty("ApiKey");
        this.revisionDate = new Date(this.getResponseProperty("RevisionDate"));
    }
}

;// ../../libs/common/src/auth/models/api/sso-config.api.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


class SsoConfigApi extends BaseResponse {
    static fromView(view, api = new SsoConfigApi()) {
        api.configType = view.configType;
        api.memberDecryptionType = view.memberDecryptionType;
        api.keyConnectorUrl = view.keyConnectorUrl;
        if (api.configType === SsoType.OpenIdConnect) {
            api.authority = view.openId.authority;
            api.clientId = view.openId.clientId;
            api.clientSecret = view.openId.clientSecret;
            api.metadataAddress = view.openId.metadataAddress;
            api.redirectBehavior = view.openId.redirectBehavior;
            api.getClaimsFromUserInfoEndpoint = view.openId.getClaimsFromUserInfoEndpoint;
            api.additionalScopes = view.openId.additionalScopes;
            api.additionalUserIdClaimTypes = view.openId.additionalUserIdClaimTypes;
            api.additionalEmailClaimTypes = view.openId.additionalEmailClaimTypes;
            api.additionalNameClaimTypes = view.openId.additionalNameClaimTypes;
            api.acrValues = view.openId.acrValues;
            api.expectedReturnAcrValue = view.openId.expectedReturnAcrValue;
        }
        else if (api.configType === SsoType.Saml2) {
            api.spUniqueEntityId = view.saml.spUniqueEntityId;
            api.spNameIdFormat = view.saml.spNameIdFormat;
            api.spOutboundSigningAlgorithm = view.saml.spOutboundSigningAlgorithm;
            api.spSigningBehavior = view.saml.spSigningBehavior;
            api.spMinIncomingSigningAlgorithm = view.saml.spMinIncomingSigningAlgorithm;
            api.spWantAssertionsSigned = view.saml.spWantAssertionsSigned;
            api.spValidateCertificates = view.saml.spValidateCertificates;
            api.idpEntityId = view.saml.idpEntityId;
            api.idpBindingType = view.saml.idpBindingType;
            api.idpSingleSignOnServiceUrl = view.saml.idpSingleSignOnServiceUrl;
            api.idpSingleLogoutServiceUrl = view.saml.idpSingleLogoutServiceUrl;
            api.idpX509PublicCert = view.saml.idpX509PublicCert;
            api.idpOutboundSigningAlgorithm = view.saml.idpOutboundSigningAlgorithm;
            api.idpAllowUnsolicitedAuthnResponse = view.saml.idpAllowUnsolicitedAuthnResponse;
            api.idpWantAuthnRequestsSigned = view.saml.idpWantAuthnRequestsSigned;
            // Value is inverted in the api model (disable instead of allow)
            api.idpDisableOutboundLogoutRequests = !view.saml.idpAllowOutboundLogoutRequests;
        }
        return api;
    }
    constructor(data = null) {
        super(data);
        if (data == null) {
            return;
        }
        this.configType = this.getResponseProperty("ConfigType");
        this.memberDecryptionType = this.getResponseProperty("MemberDecryptionType");
        this.keyConnectorUrl = this.getResponseProperty("KeyConnectorUrl");
        this.authority = this.getResponseProperty("Authority");
        this.clientId = this.getResponseProperty("ClientId");
        this.clientSecret = this.getResponseProperty("ClientSecret");
        this.metadataAddress = this.getResponseProperty("MetadataAddress");
        this.redirectBehavior = this.getResponseProperty("RedirectBehavior");
        this.getClaimsFromUserInfoEndpoint = this.getResponseProperty("GetClaimsFromUserInfoEndpoint");
        this.additionalScopes = this.getResponseProperty("AdditionalScopes");
        this.additionalUserIdClaimTypes = this.getResponseProperty("AdditionalUserIdClaimTypes");
        this.additionalEmailClaimTypes = this.getResponseProperty("AdditionalEmailClaimTypes");
        this.additionalNameClaimTypes = this.getResponseProperty("AdditionalNameClaimTypes");
        this.acrValues = this.getResponseProperty("AcrValues");
        this.expectedReturnAcrValue = this.getResponseProperty("ExpectedReturnAcrValue");
        this.spUniqueEntityId = this.getResponseProperty("SpUniqueEntityId");
        this.spNameIdFormat = this.getResponseProperty("SpNameIdFormat");
        this.spOutboundSigningAlgorithm = this.getResponseProperty("SpOutboundSigningAlgorithm");
        this.spSigningBehavior = this.getResponseProperty("SpSigningBehavior");
        this.spMinIncomingSigningAlgorithm = this.getResponseProperty("SpMinIncomingSigningAlgorithm");
        this.spWantAssertionsSigned = this.getResponseProperty("SpWantAssertionsSigned");
        this.spValidateCertificates = this.getResponseProperty("SpValidateCertificates");
        this.idpEntityId = this.getResponseProperty("IdpEntityId");
        this.idpBindingType = this.getResponseProperty("IdpBindingType");
        this.idpSingleSignOnServiceUrl = this.getResponseProperty("IdpSingleSignOnServiceUrl");
        this.idpSingleLogoutServiceUrl = this.getResponseProperty("IdpSingleLogoutServiceUrl");
        this.idpX509PublicCert = this.getResponseProperty("IdpX509PublicCert");
        this.idpOutboundSigningAlgorithm = this.getResponseProperty("IdpOutboundSigningAlgorithm");
        this.idpAllowUnsolicitedAuthnResponse = this.getResponseProperty("IdpAllowUnsolicitedAuthnResponse");
        this.idpDisableOutboundLogoutRequests = this.getResponseProperty("IdpDisableOutboundLogoutRequests");
        this.idpWantAuthnRequestsSigned = this.getResponseProperty("IdpWantAuthnRequestsSigned");
    }
}

;// ../../libs/common/src/auth/models/response/organization-sso.response.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


class OrganizationSsoResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.enabled = this.getResponseProperty("Enabled");
        this.identifier = this.getResponseProperty("Identifier");
        this.data =
            this.getResponseProperty("Data") != null
                ? new SsoConfigApi(this.getResponseProperty("Data"))
                : null;
        this.urls = new SsoUrls(this.getResponseProperty("Urls"));
    }
}
class SsoUrls extends BaseResponse {
    constructor(response) {
        super(response);
        this.callbackPath = this.getResponseProperty("CallbackPath");
        this.signedOutCallbackPath = this.getResponseProperty("SignedOutCallbackPath");
        this.spEntityId = this.getResponseProperty("SpEntityId");
        this.spEntityIdStatic = this.getResponseProperty("SpEntityIdStatic");
        this.spMetadataUrl = this.getResponseProperty("SpMetadataUrl");
        this.spAcsUrl = this.getResponseProperty("SpAcsUrl");
    }
}

;// ../../libs/common/src/billing/models/response/billing.response.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

class BillingResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.balance = this.getResponseProperty("Balance");
        const paymentSource = this.getResponseProperty("PaymentSource");
        this.paymentSource = paymentSource == null ? null : new BillingSourceResponse(paymentSource);
    }
}
class BillingSourceResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.type = this.getResponseProperty("Type");
        this.cardBrand = this.getResponseProperty("CardBrand");
        this.description = this.getResponseProperty("Description");
        this.needsVerification = this.getResponseProperty("NeedsVerification");
    }
}
class BillingInvoiceResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.id = this.getResponseProperty("Id");
        this.url = this.getResponseProperty("Url");
        this.pdfUrl = this.getResponseProperty("PdfUrl");
        this.number = this.getResponseProperty("Number");
        this.paid = this.getResponseProperty("Paid");
        this.date = this.getResponseProperty("Date");
        this.amount = this.getResponseProperty("Amount");
    }
}
class BillingTransactionResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.createdDate = this.getResponseProperty("CreatedDate");
        this.amount = this.getResponseProperty("Amount");
        this.refunded = this.getResponseProperty("Refunded");
        this.partiallyRefunded = this.getResponseProperty("PartiallyRefunded");
        this.refundedAmount = this.getResponseProperty("RefundedAmount");
        this.type = this.getResponseProperty("Type");
        this.paymentMethodType = this.getResponseProperty("PaymentMethodType");
        this.details = this.getResponseProperty("Details");
    }
}

;// ../../libs/common/src/billing/models/response/billing-history.response.ts


class BillingHistoryResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.invoices = [];
        this.transactions = [];
        const transactions = this.getResponseProperty("Transactions");
        const invoices = this.getResponseProperty("Invoices");
        if (transactions != null) {
            this.transactions = transactions.map((t) => new BillingTransactionResponse(t));
        }
        if (invoices != null) {
            this.invoices = invoices.map((i) => new BillingInvoiceResponse(i));
        }
    }
    get hasNoHistory() {
        return this.invoices.length == 0 && this.transactions.length == 0;
    }
}

;// ../../libs/common/src/billing/models/response/plan.response.ts

class PlanResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.type = this.getResponseProperty("Type");
        this.productTier = this.getResponseProperty("ProductTier");
        this.name = this.getResponseProperty("Name");
        this.isAnnual = this.getResponseProperty("IsAnnual");
        this.nameLocalizationKey = this.getResponseProperty("NameLocalizationKey");
        this.descriptionLocalizationKey = this.getResponseProperty("DescriptionLocalizationKey");
        this.canBeUsedByBusiness = this.getResponseProperty("CanBeUsedByBusiness");
        this.trialPeriodDays = this.getResponseProperty("TrialPeriodDays");
        this.hasSelfHost = this.getResponseProperty("HasSelfHost");
        this.hasPolicies = this.getResponseProperty("HasPolicies");
        this.hasMyItems = this.getResponseProperty("HasMyItems");
        this.hasGroups = this.getResponseProperty("HasGroups");
        this.hasDirectory = this.getResponseProperty("HasDirectory");
        this.hasEvents = this.getResponseProperty("HasEvents");
        this.hasTotp = this.getResponseProperty("HasTotp");
        this.has2fa = this.getResponseProperty("Has2fa");
        this.hasApi = this.getResponseProperty("HasApi");
        this.hasSso = this.getResponseProperty("HasSso");
        this.hasResetPassword = this.getResponseProperty("HasResetPassword");
        this.usersGetPremium = this.getResponseProperty("UsersGetPremium");
        this.upgradeSortOrder = this.getResponseProperty("UpgradeSortOrder");
        this.displaySortOrder = this.getResponseProperty("DisplaySortOrder");
        this.legacyYear = this.getResponseProperty("LegacyYear");
        this.disabled = this.getResponseProperty("Disabled");
        const passwordManager = this.getResponseProperty("PasswordManager");
        const secretsManager = this.getResponseProperty("SecretsManager");
        this.PasswordManager =
            passwordManager == null ? null : new PasswordManagerPlanFeaturesResponse(passwordManager);
        this.SecretsManager =
            secretsManager == null ? null : new SecretsManagerPlanFeaturesResponse(secretsManager);
    }
}
class SecretsManagerPlanFeaturesResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.stripeSeatPlanId = this.getResponseProperty("StripeSeatPlanId");
        this.baseSeats = this.getResponseProperty("BaseSeats");
        this.basePrice = this.getResponseProperty("BasePrice");
        this.seatPrice = this.getResponseProperty("SeatPrice");
        this.hasAdditionalSeatsOption = this.getResponseProperty("HasAdditionalSeatsOption");
        this.maxAdditionalSeats = this.getResponseProperty("MaxAdditionalSeats");
        this.maxSeats = this.getResponseProperty("MaxSeats");
        this.stripeServiceAccountPlanId = this.getResponseProperty("StripeServiceAccountPlanId");
        this.additionalPricePerServiceAccount = this.getResponseProperty("AdditionalPricePerServiceAccount");
        this.baseServiceAccount = this.getResponseProperty("BaseServiceAccount");
        this.maxServiceAccount = this.getResponseProperty("MaxServiceAccount");
        this.hasAdditionalServiceAccountOption = this.getResponseProperty("HasAdditionalServiceAccountOption");
        this.maxAdditionalServiceAccounts = this.getResponseProperty("MaxAdditionalServiceAccounts");
        this.maxProjects = this.getResponseProperty("MaxProjects");
    }
}
class PasswordManagerPlanFeaturesResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.stripePlanId = this.getResponseProperty("StripePlanId");
        this.stripeSeatPlanId = this.getResponseProperty("StripeSeatPlanId");
        this.stripeProviderPortalSeatPlanId = this.getResponseProperty("StripeProviderPortalSeatPlanId");
        this.stripeStoragePlanId = this.getResponseProperty("StripeStoragePlanId");
        this.stripePremiumAccessPlanId = this.getResponseProperty("StripePremiumAccessPlanId");
        this.basePrice = this.getResponseProperty("BasePrice");
        this.seatPrice = this.getResponseProperty("SeatPrice");
        this.providerPortalSeatPrice = this.getResponseProperty("ProviderPortalSeatPrice");
        this.baseSeats = this.getResponseProperty("BaseSeats");
        this.maxAdditionalSeats = this.getResponseProperty("MaxAdditionalSeats");
        this.premiumAccessOptionPrice = this.getResponseProperty("PremiumAccessOptionPrice");
        this.maxSeats = this.getResponseProperty("MaxSeats");
        this.additionalStoragePricePerGb = this.getResponseProperty("AdditionalStoragePricePerGb");
        this.hasAdditionalSeatsOption = this.getResponseProperty("HasAdditionalSeatsOption");
        this.baseStorageGb = this.getResponseProperty("BaseStorageGb");
        this.maxCollections = this.getResponseProperty("MaxCollections");
        this.hasAdditionalStorageOption = this.getResponseProperty("HasAdditionalStorageOption");
        this.maxAdditionalStorage = this.getResponseProperty("MaxAdditionalStorage");
        this.hasPremiumAccessOption = this.getResponseProperty("HasPremiumAccessOption");
    }
}

;// ../../libs/common/src/admin-console/models/response/organization.response.ts


class organization_response_OrganizationResponse extends BaseResponse {
    constructor(response) {
        var _a, _b, _c;
        super(response);
        this.id = this.getResponseProperty("Id");
        this.name = this.getResponseProperty("Name");
        this.businessName = this.getResponseProperty("BusinessName");
        this.businessAddress1 = this.getResponseProperty("BusinessAddress1");
        this.businessAddress2 = this.getResponseProperty("BusinessAddress2");
        this.businessAddress3 = this.getResponseProperty("BusinessAddress3");
        this.businessCountry = this.getResponseProperty("BusinessCountry");
        this.businessTaxNumber = this.getResponseProperty("BusinessTaxNumber");
        this.billingEmail = this.getResponseProperty("BillingEmail");
        const plan = this.getResponseProperty("Plan");
        this.plan = plan == null ? null : new PlanResponse(plan);
        this.planType = this.getResponseProperty("PlanType");
        this.seats = this.getResponseProperty("Seats");
        this.maxAutoscaleSeats = this.getResponseProperty("MaxAutoscaleSeats");
        this.maxCollections = this.getResponseProperty("MaxCollections");
        this.maxStorageGb = this.getResponseProperty("MaxStorageGb");
        this.useGroups = this.getResponseProperty("UseGroups");
        this.useDirectory = this.getResponseProperty("UseDirectory");
        this.useEvents = this.getResponseProperty("UseEvents");
        this.useTotp = this.getResponseProperty("UseTotp");
        this.use2fa = this.getResponseProperty("Use2fa");
        this.useApi = this.getResponseProperty("UseApi");
        this.useResetPassword = this.getResponseProperty("UseResetPassword");
        this.useSecretsManager = this.getResponseProperty("UseSecretsManager");
        this.hasPublicAndPrivateKeys = this.getResponseProperty("HasPublicAndPrivateKeys");
        this.usePasswordManager = this.getResponseProperty("UsePasswordManager");
        this.smSeats = this.getResponseProperty("SmSeats");
        this.smServiceAccounts = this.getResponseProperty("SmServiceAccounts");
        this.maxAutoscaleSmSeats = this.getResponseProperty("MaxAutoscaleSmSeats");
        this.maxAutoscaleSmServiceAccounts = this.getResponseProperty("MaxAutoscaleSmServiceAccounts");
        this.limitCollectionCreation = this.getResponseProperty("LimitCollectionCreation");
        this.limitCollectionDeletion = this.getResponseProperty("LimitCollectionDeletion");
        this.limitItemDeletion = this.getResponseProperty("LimitItemDeletion");
        this.allowAdminAccessToAllCollectionItems = this.getResponseProperty("AllowAdminAccessToAllCollectionItems");
        this.useDisableSMAdsForUsers = (_a = this.getResponseProperty("UseDisableSMAdsForUsers")) !== null && _a !== void 0 ? _a : false;
        // Map from backend API property (UseRiskInsights) to domain model property (useAccessIntelligence)
        this.useAccessIntelligence = this.getResponseProperty("UseRiskInsights");
        this.usePhishingBlocker = (_b = this.getResponseProperty("UsePhishingBlocker")) !== null && _b !== void 0 ? _b : false;
        this.useMyItems = (_c = this.getResponseProperty("UseMyItems")) !== null && _c !== void 0 ? _c : false;
    }
}

;// ../../libs/common/src/billing/models/response/subscription.response.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


class SubscriptionResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.storageName = this.getResponseProperty("StorageName");
        this.storageGb = this.getResponseProperty("StorageGb");
        this.maxStorageGb = this.getResponseProperty("MaxStorageGb");
        this.license = this.getResponseProperty("License");
        this.expiration = this.getResponseProperty("Expiration");
        const subscription = this.getResponseProperty("Subscription");
        const upcomingInvoice = this.getResponseProperty("UpcomingInvoice");
        const customerDiscount = this.getResponseProperty("CustomerDiscount");
        this.subscription = subscription == null ? null : new BillingSubscriptionResponse(subscription);
        this.upcomingInvoice =
            upcomingInvoice == null
                ? null
                : new BillingSubscriptionUpcomingInvoiceResponse(upcomingInvoice);
        this.customerDiscount =
            customerDiscount == null ? null : new BillingCustomerDiscount(customerDiscount);
    }
}
class BillingSubscriptionResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.items = [];
        this.trialStartDate = this.getResponseProperty("TrialStartDate");
        this.trialEndDate = this.getResponseProperty("TrialEndDate");
        this.periodStartDate = this.getResponseProperty("PeriodStartDate");
        this.periodEndDate = this.getResponseProperty("PeriodEndDate");
        this.cancelledDate = this.getResponseProperty("CancelledDate");
        this.cancelAtEndDate = this.getResponseProperty("CancelAtEndDate");
        this.status = this.getResponseProperty("Status");
        this.cancelled = this.getResponseProperty("Cancelled");
        const items = this.getResponseProperty("Items");
        if (items != null) {
            this.items = items.map((i) => new BillingSubscriptionItemResponse(i));
        }
        this.collectionMethod = this.getResponseProperty("CollectionMethod");
        this.suspensionDate = this.getResponseProperty("SuspensionDate");
        this.unpaidPeriodEndDate = this.getResponseProperty("unpaidPeriodEndDate");
        this.gracePeriod = this.getResponseProperty("GracePeriod");
    }
}
class BillingSubscriptionItemResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.productId = this.getResponseProperty("ProductId");
        this.name = this.getResponseProperty("Name");
        this.amount = this.getResponseProperty("Amount");
        this.quantity = this.getResponseProperty("Quantity");
        this.interval = this.getResponseProperty("Interval");
        this.sponsoredSubscriptionItem = this.getResponseProperty("SponsoredSubscriptionItem");
        this.addonSubscriptionItem = this.getResponseProperty("AddonSubscriptionItem");
    }
}
class BillingSubscriptionUpcomingInvoiceResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.date = this.getResponseProperty("Date");
        this.amount = this.getResponseProperty("Amount");
    }
}

;// ../../libs/common/src/billing/models/response/organization-subscription.response.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore



class OrganizationSubscriptionResponse extends organization_response_OrganizationResponse {
    constructor(response) {
        super(response);
        this.storageName = this.getResponseProperty("StorageName");
        this.storageGb = this.getResponseProperty("StorageGb");
        const subscription = this.getResponseProperty("Subscription");
        this.subscription = subscription == null ? null : new BillingSubscriptionResponse(subscription);
        const upcomingInvoice = this.getResponseProperty("UpcomingInvoice");
        this.upcomingInvoice =
            upcomingInvoice == null
                ? null
                : new BillingSubscriptionUpcomingInvoiceResponse(upcomingInvoice);
        const customerDiscount = this.getResponseProperty("CustomerDiscount");
        this.customerDiscount =
            customerDiscount == null ? null : new BillingCustomerDiscount(customerDiscount);
        this.expiration = this.getResponseProperty("Expiration");
        this.expirationWithoutGracePeriod = this.getResponseProperty("ExpirationWithoutGracePeriod");
    }
}
class BillingCustomerDiscount extends BaseResponse {
    constructor(response) {
        super(response);
        this.id = this.getResponseProperty("Id");
        this.active = this.getResponseProperty("Active");
        this.percentOff = this.getResponseProperty("PercentOff");
        this.amountOff = this.getResponseProperty("AmountOff");
        this.appliesTo = this.getResponseProperty("AppliesTo") || [];
    }
}

;// ../../libs/common/src/admin-console/models/response/profile-organization.response.ts


class ProfileOrganizationResponse extends BaseResponse {
    constructor(response) {
        var _a, _b, _c, _d, _e, _f, _g, _h;
        super(response);
        this.id = this.getResponseProperty("Id");
        this.name = this.getResponseProperty("Name");
        this.usePolicies = this.getResponseProperty("UsePolicies");
        this.useGroups = this.getResponseProperty("UseGroups");
        this.useDirectory = this.getResponseProperty("UseDirectory");
        this.useEvents = this.getResponseProperty("UseEvents");
        this.useTotp = this.getResponseProperty("UseTotp");
        this.use2fa = this.getResponseProperty("Use2fa");
        this.useApi = this.getResponseProperty("UseApi");
        this.useSso = this.getResponseProperty("UseSso");
        this.useOrganizationDomains = this.getResponseProperty("UseOrganizationDomains");
        this.useKeyConnector = (_a = this.getResponseProperty("UseKeyConnector")) !== null && _a !== void 0 ? _a : false;
        this.useScim = (_b = this.getResponseProperty("UseScim")) !== null && _b !== void 0 ? _b : false;
        this.useCustomPermissions = (_c = this.getResponseProperty("UseCustomPermissions")) !== null && _c !== void 0 ? _c : false;
        this.useResetPassword = this.getResponseProperty("UseResetPassword");
        this.useSecretsManager = this.getResponseProperty("UseSecretsManager");
        this.usePasswordManager = this.getResponseProperty("UsePasswordManager");
        this.useActivateAutofillPolicy = this.getResponseProperty("UseActivateAutofillPolicy");
        this.useAutomaticUserConfirmation = this.getResponseProperty("UseAutomaticUserConfirmation");
        this.selfHost = this.getResponseProperty("SelfHost");
        this.usersGetPremium = this.getResponseProperty("UsersGetPremium");
        this.seats = this.getResponseProperty("Seats");
        this.maxCollections = this.getResponseProperty("MaxCollections");
        this.maxStorageGb = this.getResponseProperty("MaxStorageGb");
        this.key = this.getResponseProperty("Key");
        this.hasPublicAndPrivateKeys = this.getResponseProperty("HasPublicAndPrivateKeys");
        this.status = this.getResponseProperty("Status");
        this.type = this.getResponseProperty("Type");
        this.enabled = this.getResponseProperty("Enabled");
        this.ssoBound = this.getResponseProperty("SsoBound");
        this.identifier = this.getResponseProperty("Identifier");
        this.permissions = new PermissionsApi(this.getResponseProperty("permissions"));
        this.resetPasswordEnrolled = this.getResponseProperty("ResetPasswordEnrolled");
        this.userId = this.getResponseProperty("UserId");
        this.organizationUserId = this.getResponseProperty("OrganizationUserId");
        this.providerId = this.getResponseProperty("ProviderId");
        this.providerName = this.getResponseProperty("ProviderName");
        this.providerType = this.getResponseProperty("ProviderType");
        this.familySponsorshipFriendlyName = this.getResponseProperty("FamilySponsorshipFriendlyName");
        this.familySponsorshipAvailable = this.getResponseProperty("FamilySponsorshipAvailable");
        this.productTierType = this.getResponseProperty("ProductTierType");
        this.keyConnectorEnabled = (_d = this.getResponseProperty("KeyConnectorEnabled")) !== null && _d !== void 0 ? _d : false;
        this.keyConnectorUrl = this.getResponseProperty("KeyConnectorUrl");
        const familySponsorshipLastSyncDateString = this.getResponseProperty("FamilySponsorshipLastSyncDate");
        if (familySponsorshipLastSyncDateString) {
            this.familySponsorshipLastSyncDate = new Date(familySponsorshipLastSyncDateString);
        }
        const familySponsorshipValidUntilString = this.getResponseProperty("FamilySponsorshipValidUntil");
        if (familySponsorshipValidUntilString) {
            this.familySponsorshipValidUntil = new Date(familySponsorshipValidUntilString);
        }
        this.familySponsorshipToDelete = this.getResponseProperty("FamilySponsorshipToDelete");
        this.accessSecretsManager = this.getResponseProperty("AccessSecretsManager");
        this.limitCollectionCreation = this.getResponseProperty("LimitCollectionCreation");
        this.limitCollectionDeletion = this.getResponseProperty("LimitCollectionDeletion");
        this.limitItemDeletion = this.getResponseProperty("LimitItemDeletion");
        this.allowAdminAccessToAllCollectionItems = this.getResponseProperty("AllowAdminAccessToAllCollectionItems");
        this.userIsManagedByOrganization = this.getResponseProperty("UserIsManagedByOrganization");
        // Map from backend API property (UseRiskInsights) to domain model property (useAccessIntelligence)
        this.useAccessIntelligence = this.getResponseProperty("UseRiskInsights");
        this.useAdminSponsoredFamilies = this.getResponseProperty("UseAdminSponsoredFamilies");
        this.useDisableSMAdsForUsers = (_e = this.getResponseProperty("UseDisableSMAdsForUsers")) !== null && _e !== void 0 ? _e : false;
        this.isAdminInitiated = this.getResponseProperty("IsAdminInitiated");
        this.ssoEnabled = (_f = this.getResponseProperty("SsoEnabled")) !== null && _f !== void 0 ? _f : false;
        this.ssoMemberDecryptionType = this.getResponseProperty("SsoMemberDecryptionType");
        this.usePhishingBlocker = (_g = this.getResponseProperty("UsePhishingBlocker")) !== null && _g !== void 0 ? _g : false;
        this.useMyItems = (_h = this.getResponseProperty("UseMyItems")) !== null && _h !== void 0 ? _h : false;
    }
}

;// ../../libs/common/src/admin-console/models/response/profile-provider-organization.response.ts

class ProfileProviderOrganizationResponse extends ProfileOrganizationResponse {
    constructor(response) {
        super(response);
        this.keyConnectorEnabled = false;
    }
}

;// ../../libs/common/src/admin-console/models/response/profile-provider.response.ts


class ProfileProviderResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.id = this.getResponseProperty("Id");
        this.name = this.getResponseProperty("Name");
        this.key = this.getResponseProperty("Key");
        this.status = this.getResponseProperty("Status");
        this.type = this.getResponseProperty("Type");
        this.enabled = this.getResponseProperty("Enabled");
        this.permissions = new PermissionsApi(this.getResponseProperty("permissions"));
        this.userId = this.getResponseProperty("UserId");
        this.useEvents = this.getResponseProperty("UseEvents");
        this.providerStatus = this.getResponseProperty("ProviderStatus");
        this.providerType = this.getResponseProperty("ProviderType");
    }
}

;// ../../libs/common/src/models/response/profile.response.ts






class ProfileResponse extends BaseResponse {
    constructor(response) {
        var _a, _b, _c;
        super(response);
        // Cleanup: This should be non-optional after the server has been released for a while https://bitwarden.atlassian.net/browse/PM-21768
        this.accountKeys = null;
        this.organizations = [];
        this.providers = [];
        this.providerOrganizations = [];
        this.id = this.getResponseProperty("Id");
        this.name = this.getResponseProperty("Name");
        this.email = this.getResponseProperty("Email");
        this.emailVerified = this.getResponseProperty("EmailVerified");
        this.premiumPersonally = this.getResponseProperty("Premium");
        this.premiumFromOrganization = this.getResponseProperty("PremiumFromOrganization");
        this.culture = this.getResponseProperty("Culture");
        this.twoFactorEnabled = this.getResponseProperty("TwoFactorEnabled");
        const key = this.getResponseProperty("Key");
        if (key) {
            this.key = new enc_string_EncString(key);
        }
        // Cleanup: This should be non-optional after the server has been released for a while https://bitwarden.atlassian.net/browse/PM-21768
        if (this.getResponseProperty("AccountKeys") != null) {
            this.accountKeys = new PrivateKeysResponseModel(this.getResponseProperty("AccountKeys"));
        }
        this.avatarColor = this.getResponseProperty("AvatarColor");
        this.creationDate = this.getResponseProperty("CreationDate");
        this.privateKey = this.getResponseProperty("PrivateKey");
        this.securityStamp = this.getResponseProperty("SecurityStamp");
        this.forcePasswordReset = (_a = this.getResponseProperty("ForcePasswordReset")) !== null && _a !== void 0 ? _a : false;
        this.usesKeyConnector = (_b = this.getResponseProperty("UsesKeyConnector")) !== null && _b !== void 0 ? _b : false;
        this.verifyDevices = (_c = this.getResponseProperty("VerifyDevices")) !== null && _c !== void 0 ? _c : true;
        const organizations = this.getResponseProperty("Organizations");
        if (organizations != null) {
            this.organizations = organizations.map((o) => new ProfileOrganizationResponse(o));
        }
        const providers = this.getResponseProperty("Providers");
        if (providers != null) {
            this.providers = providers.map((o) => new ProfileProviderResponse(o));
        }
        const providerOrganizations = this.getResponseProperty("ProviderOrganizations");
        if (providerOrganizations != null) {
            this.providerOrganizations = providerOrganizations.map((o) => new ProfileProviderOrganizationResponse(o));
        }
    }
}

;// ../../libs/common/src/billing/models/response/payment.response.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


class PaymentResponse extends BaseResponse {
    constructor(response) {
        super(response);
        const userProfile = this.getResponseProperty("UserProfile");
        if (userProfile != null) {
            this.userProfile = new ProfileResponse(userProfile);
        }
        this.paymentIntentClientSecret = this.getResponseProperty("PaymentIntentClientSecret");
        this.success = this.getResponseProperty("Success");
    }
}

;// ../../libs/common/src/admin-console/models/response/organization-api-key-information.response.ts

class OrganizationApiKeyInformationResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.keyType = this.getResponseProperty("KeyType");
    }
}

;// ../../libs/common/src/admin-console/models/response/organization-auto-enroll-status.response.ts

class OrganizationAutoEnrollStatusResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.id = this.getResponseProperty("Id");
        this.resetPasswordEnabled = this.getResponseProperty("ResetPasswordEnabled");
    }
}

;// ../../libs/common/src/models/response/keys.response.ts

class KeysResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.privateKey = this.getResponseProperty("PrivateKey");
        this.publicKey = this.getResponseProperty("PublicKey");
    }
}

;// ../../libs/common/src/admin-console/models/response/organization-keys.response.ts

class OrganizationKeysResponse extends KeysResponse {
    constructor(response) {
        super(response);
    }
}

;// ../../libs/common/src/admin-console/services/organization/organization-api.service.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
var organization_api_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};












class OrganizationApiService {
    constructor(apiService, syncService) {
        this.apiService = apiService;
        this.syncService = syncService;
    }
    get(id) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("GET", "/organizations/" + id, null, true, true);
            return new organization_response_OrganizationResponse(r);
        });
    }
    getBilling(id) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("GET", "/organizations/" + id + "/billing", null, true, true);
            return new BillingResponse(r);
        });
    }
    getBillingHistory(id) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("GET", "/organizations/" + id + "/billing/history", null, true, true);
            return new BillingHistoryResponse(r);
        });
    }
    getSubscription(id) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("GET", "/organizations/" + id + "/subscription", null, true, true);
            return new OrganizationSubscriptionResponse(r);
        });
    }
    getLicense(id, installationId) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            return this.apiService.send("GET", "/organizations/" + id + "/license?installationId=" + installationId, null, true, true);
        });
    }
    getAutoEnrollStatus(identifier) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("GET", "/organizations/" + identifier + "/auto-enroll-status", null, true, true);
            return new OrganizationAutoEnrollStatusResponse(r);
        });
    }
    create(request) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("POST", "/organizations", request, true, true);
            // Forcing a sync will notify organization service that they need to repull
            yield this.syncService.fullSync(true);
            return new organization_response_OrganizationResponse(r);
        });
    }
    createWithoutPayment(request) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("POST", "/organizations/create-without-payment", request, true, true);
            // Forcing a sync will notify organization service that they need to repull
            yield this.syncService.fullSync(true);
            return new organization_response_OrganizationResponse(r);
        });
    }
    createLicense(data) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("POST", "/organizations/licenses/self-hosted", data, true, true);
            return new organization_response_OrganizationResponse(r);
        });
    }
    save(id, request) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("PUT", "/organizations/" + id, request, true, true);
            const data = new organization_response_OrganizationResponse(r);
            yield this.syncService.fullSync(true);
            return data;
        });
    }
    upgrade(id, request) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("POST", "/organizations/" + id + "/upgrade", request, true, true);
            return new PaymentResponse(r);
        });
    }
    updatePasswordManagerSeats(id, request) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("POST", "/organizations/" + id + "/subscription", request, true, true);
            return new ProfileOrganizationResponse(r);
        });
    }
    updateSecretsManagerSubscription(id, request) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("POST", "/organizations/" + id + "/sm-subscription", request, true, true);
            return new ProfileOrganizationResponse(r);
        });
    }
    updateSeats(id, request) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("POST", "/organizations/" + id + "/seat", request, true, true);
            return new PaymentResponse(r);
        });
    }
    updateStorage(id, request) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("POST", "/organizations/" + id + "/storage", request, true, true);
            return new PaymentResponse(r);
        });
    }
    reinstate(id) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            return this.apiService.send("POST", "/organizations/" + id + "/reinstate", null, true, false);
        });
    }
    leave(id) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            yield this.apiService.send("POST", "/organizations/" + id + "/leave", null, true, false);
            yield this.syncService.fullSync(true);
        });
    }
    delete(id, request) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            yield this.apiService.send("DELETE", "/organizations/" + id, request, true, false);
            yield this.syncService.fullSync(true);
        });
    }
    deleteUsingToken(organizationId, request) {
        return this.apiService.send("POST", "/organizations/" + organizationId + "/delete-recover-token", request, false, false);
    }
    updateLicense(id, data) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            yield this.apiService.send("POST", "/organizations/licenses/self-hosted/" + id, data, true, false);
        });
    }
    importDirectory(organizationId, request) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            return this.apiService.send("POST", "/organizations/" + organizationId + "/import", request, true, false);
        });
    }
    getOrCreateApiKey(id, request) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("POST", "/organizations/" + id + "/api-key", request, true, true);
            return new ApiKeyResponse(r);
        });
    }
    getApiKeyInformation(id_1) {
        return organization_api_service_awaiter(this, arguments, void 0, function* (id, organizationApiKeyType = null) {
            const uri = organizationApiKeyType === null
                ? "/organizations/" + id + "/api-key-information"
                : "/organizations/" + id + "/api-key-information/" + organizationApiKeyType;
            const r = yield this.apiService.send("GET", uri, null, true, true);
            return new ListResponse(r, OrganizationApiKeyInformationResponse);
        });
    }
    rotateApiKey(id, request) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("POST", "/organizations/" + id + "/rotate-api-key", request, true, true);
            return new ApiKeyResponse(r);
        });
    }
    getKeys(id) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("GET", "/organizations/" + id + "/keys", null, true, true);
            return new OrganizationKeysResponse(r);
        });
    }
    updateKeys(id, request) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("POST", "/organizations/" + id + "/keys", request, true, true);
            // Not broadcasting anything because data on this response doesn't correspond to `Organization`
            return new OrganizationKeysResponse(r);
        });
    }
    getSso(id) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("GET", "/organizations/" + id + "/sso", null, true, true);
            return new OrganizationSsoResponse(r);
        });
    }
    updateSso(id, request) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("POST", "/organizations/" + id + "/sso", request, true, true);
            // Not broadcasting anything because data on this response doesn't correspond to `Organization`
            return new OrganizationSsoResponse(r);
        });
    }
    selfHostedSyncLicense(id) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            yield this.apiService.send("POST", "/organizations/licenses/self-hosted/" + id + "/sync/", null, true, false);
        });
    }
    subscribeToSecretsManager(id, request) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("POST", "/organizations/" + id + "/subscribe-secrets-manager", request, true, true);
            return new ProfileOrganizationResponse(r);
        });
    }
    updateCollectionManagement(id, request) {
        return organization_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("PUT", "/organizations/" + id + "/collection-management", request, true, true);
            const data = new organization_response_OrganizationResponse(r);
            yield this.syncService.fullSync(true);
            return data;
        });
    }
}

;// ../../libs/common/src/admin-console/models/response/policy.response.ts

class PolicyResponse extends BaseResponse {
    constructor(response) {
        var _a;
        super(response);
        this.id = this.getResponseProperty("Id");
        this.organizationId = this.getResponseProperty("OrganizationId");
        this.type = this.getResponseProperty("Type");
        this.data = this.getResponseProperty("Data");
        this.enabled = this.getResponseProperty("Enabled");
        this.canToggleState = (_a = this.getResponseProperty("CanToggleState")) !== null && _a !== void 0 ? _a : true;
        this.revisionDate = this.getResponseProperty("RevisionDate");
    }
}

;// ../../libs/common/src/admin-console/services/policy/policy-api.service.ts
var policy_api_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};









class PolicyApiService {
    constructor(policyService, apiService, accountService) {
        this.policyService = policyService;
        this.apiService = apiService;
        this.accountService = accountService;
    }
    getPolicy(organizationId, type) {
        return policy_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("GET", "/organizations/" + organizationId + "/policies/" + type, null, true, true);
            return new PolicyResponse(r);
        });
    }
    getPolicies(organizationId) {
        return policy_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("GET", "/organizations/" + organizationId + "/policies", null, true, true);
            return new ListResponse(r, PolicyResponse);
        });
    }
    getPoliciesByToken(organizationId, token, email, organizationUserId) {
        return policy_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("GET", "/organizations/" +
                organizationId +
                "/policies/token?" +
                "token=" +
                encodeURIComponent(token) +
                "&email=" +
                utils_Utils.encodeRFC3986URIComponent(email) +
                "&organizationUserId=" +
                organizationUserId, null, false, true);
            return Policy.fromListResponse(new ListResponse(r, PolicyResponse));
        });
    }
    getMasterPasswordPolicyResponseForOrgUser(organizationId) {
        return policy_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.send("GET", "/organizations/" + organizationId + "/policies/master-password", null, true, true);
            return new PolicyResponse(response);
        });
    }
    getMasterPasswordPolicyOptsForOrgUser(orgId) {
        return policy_api_service_awaiter(this, void 0, void 0, function* () {
            try {
                const masterPasswordPolicyResponse = yield this.getMasterPasswordPolicyResponseForOrgUser(orgId);
                const masterPasswordPolicy = Policy.fromResponse(masterPasswordPolicyResponse);
                if (!masterPasswordPolicy) {
                    return null;
                }
                return (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId, (0,external_rxjs_namespaceObject.switchMap)((userId) => this.policyService.masterPasswordPolicyOptions$(userId, [masterPasswordPolicy])), (0,external_rxjs_namespaceObject.map)((policy) => policy !== null && policy !== void 0 ? policy : null)));
            }
            catch (error) {
                // If policy not found, return null
                if (error instanceof ErrorResponse && error.statusCode === HttpStatusCode.NotFound) {
                    return null;
                }
                // otherwise rethrow error
                throw error;
            }
        });
    }
    putPolicy(organizationId, type, request) {
        return policy_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.send("PUT", "/organizations/" + organizationId + "/policies/" + type, request, true, true);
            yield this.handleResponse(response);
        });
    }
    putPolicyVNext(organizationId, type, request) {
        return policy_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.send("PUT", `/organizations/${organizationId}/policies/${type}/vnext`, request, true, true);
            yield this.handleResponse(response);
        });
    }
    handleResponse(response) {
        return policy_api_service_awaiter(this, void 0, void 0, function* () {
            const userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
            const policyResponse = new PolicyResponse(response);
            const data = new PolicyData(policyResponse);
            yield this.policyService.upsert(data, userId);
        });
    }
}

;// ../../libs/common/src/admin-console/models/response/addable-organization.response.ts

class AddableOrganizationResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.id = this.getResponseProperty("id");
        this.plan = this.getResponseProperty("plan");
        this.name = this.getResponseProperty("name");
        this.seats = this.getResponseProperty("seats");
        this.disabled = this.getResponseProperty("disabled");
    }
}

;// ../../libs/common/src/admin-console/models/response/provider/provider-organization.response.ts

class ProviderOrganizationResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.id = this.getResponseProperty("Id");
        this.providerId = this.getResponseProperty("ProviderId");
        this.organizationId = this.getResponseProperty("OrganizationId");
        this.key = this.getResponseProperty("Key");
        this.settings = this.getResponseProperty("Settings");
        this.creationDate = this.getResponseProperty("CreationDate");
        this.revisionDate = this.getResponseProperty("RevisionDate");
        this.userCount = this.getResponseProperty("UserCount");
        this.seats = this.getResponseProperty("Seats");
        this.occupiedSeats = this.getResponseProperty("OccupiedSeats");
        this.remainingSeats = this.getResponseProperty("RemainingSeats");
        this.plan = this.getResponseProperty("Plan");
    }
}
class ProviderOrganizationOrganizationDetailsResponse extends ProviderOrganizationResponse {
    constructor(response) {
        super(response);
        this.organizationName = this.getResponseProperty("OrganizationName");
    }
}

;// ../../libs/common/src/admin-console/models/response/provider/provider.response.ts

class ProviderResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.id = this.getResponseProperty("Id");
        this.name = this.getResponseProperty("Name");
        this.businessName = this.getResponseProperty("BusinessName");
        this.billingEmail = this.getResponseProperty("BillingEmail");
        this.creationDate = this.getResponseProperty("CreationDate");
        this.type = this.getResponseProperty("Type");
    }
}

;// ../../libs/common/src/admin-console/services/provider/provider-api.service.ts
var provider_api_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};




class ProviderApiService {
    constructor(apiService) {
        this.apiService = apiService;
    }
    postProviderSetup(id, request) {
        return provider_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("POST", "/providers/" + id + "/setup", request, true, true);
            return new ProviderResponse(r);
        });
    }
    getProvider(id) {
        return provider_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("GET", "/providers/" + id, null, true, true);
            return new ProviderResponse(r);
        });
    }
    putProvider(id, request) {
        return provider_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("PUT", "/providers/" + id, request, true, true);
            return new ProviderResponse(r);
        });
    }
    providerRecoverDeleteToken(providerId, request) {
        return this.apiService.send("POST", "/providers/" + providerId + "/delete-recover-token", request, false, false);
    }
    deleteProvider(id) {
        return provider_api_service_awaiter(this, void 0, void 0, function* () {
            yield this.apiService.send("DELETE", "/providers/" + id, null, true, false);
        });
    }
    getProviderOrganizations(providerId) {
        return provider_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.send("GET", "/providers/" + providerId + "/organizations", null, true, true);
            return new ListResponse(response, ProviderOrganizationOrganizationDetailsResponse);
        });
    }
    getProviderAddableOrganizations(providerId) {
        return provider_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.send("GET", "/providers/" + providerId + "/clients/addable", null, true, true);
            return response.map((data) => new AddableOrganizationResponse(data));
        });
    }
    addOrganizationToProvider(providerId, request) {
        return this.apiService.send("POST", "/providers/" + providerId + "/clients/existing", request, true, false);
    }
    updateProviderOrganization(providerId, organizationId, request) {
        return provider_api_service_awaiter(this, void 0, void 0, function* () {
            return yield this.apiService.send("PUT", "/providers/" + providerId + "/clients/" + organizationId, request, true, false);
        });
    }
    createProviderOrganization(providerId, request) {
        return this.apiService.send("POST", "/providers/" + providerId + "/clients", request, true, false);
    }
}

;// ../../libs/common/src/admin-console/models/domain/provider.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

class Provider {
    constructor(obj) {
        if (obj == null) {
            return;
        }
        this.id = obj.id;
        this.name = obj.name;
        this.status = obj.status;
        this.type = obj.type;
        this.enabled = obj.enabled;
        this.userId = obj.userId;
        this.useEvents = obj.useEvents;
        this.providerStatus = obj.providerStatus;
        this.providerType = obj.providerType;
    }
    get canAccess() {
        if (this.isProviderAdmin) {
            return true;
        }
        return this.enabled && this.status === ProviderUserStatusType.Confirmed;
    }
    get canCreateOrganizations() {
        return this.enabled && this.isProviderAdmin;
    }
    get canManageUsers() {
        return this.isProviderAdmin;
    }
    get canAccessEventLogs() {
        return this.isProviderAdmin;
    }
    get isProviderAdmin() {
        return this.type === ProviderUserType.ProviderAdmin;
    }
}

;// ../../libs/common/src/admin-console/services/provider.service.ts
var provider_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};




const PROVIDERS = UserKeyDefinition.record(PROVIDERS_DISK, "providers", {
    deserializer: (obj) => obj,
    clearOn: ["logout"],
});
class ProviderService {
    constructor(stateProvider) {
        this.stateProvider = stateProvider;
    }
    providers$(userId) {
        return this.stateProvider
            .getUser(userId, PROVIDERS)
            .state$.pipe(this.mapProviderRecordToArray());
    }
    mapProviderRecordToArray() {
        return (0,external_rxjs_namespaceObject.map)((providers) => Object.values(providers !== null && providers !== void 0 ? providers : {}).map((o) => new Provider(o)));
    }
    get$(id, userId) {
        return this.providers$(userId).pipe(getById(id));
    }
    save(providers, userId) {
        return provider_service_awaiter(this, void 0, void 0, function* () {
            yield this.stateProvider.setUserState(PROVIDERS, providers, userId);
        });
    }
}

;// ../../libs/common/src/auth/password-prelogin/password-prelogin.model.ts
// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop.
// eslint-disable-next-line no-restricted-imports

/**
 * Domain model representing the server's prelogin response for password-based authentication.
 * Contains the KDF configuration needed to derive the master key from the user's master password.
 */
class PasswordPreloginData {
    constructor(kdfConfig) {
        this.kdfConfig = kdfConfig;
    }
    /**
     * Creates a PasswordPreloginData instance from a prelogin API response.
     * @param response The raw API response from the prelogin endpoint.
     */
    static fromResponse(response) {
        const kdfConfig = response.kdf === kdf_type_enum_KdfType.PBKDF2_SHA256
            ? new PBKDF2KdfConfig(response.kdfIterations)
            : new Argon2KdfConfig(response.kdfIterations, response.kdfMemory, response.kdfParallelism);
        kdfConfig.validateKdfConfigForPrelogin();
        return new PasswordPreloginData(kdfConfig);
    }
}

;// ../../libs/common/src/auth/password-prelogin/password-prelogin.request.ts
class PasswordPreloginRequest {
    constructor(email) {
        this.email = email;
    }
}

;// ../../libs/common/src/auth/password-prelogin/default-password-prelogin.service.ts



class DefaultPasswordPreloginService {
    constructor(passwordPreloginApiService) {
        this.passwordPreloginApiService = passwordPreloginApiService;
        this.currentEmail = null;
        this.currentPreloginData$ = null;
    }
    getPreloginData$(email) {
        const normalized = email.trim().toLowerCase();
        if (normalized === this.currentEmail && this.currentPreloginData$ !== null) {
            return this.currentPreloginData$;
        }
        this.currentEmail = normalized;
        this.currentPreloginData$ = (0,external_rxjs_namespaceObject.from)(this.passwordPreloginApiService.getPreloginData(new PasswordPreloginRequest(normalized))).pipe((0,external_rxjs_namespaceObject.map)(PasswordPreloginData.fromResponse), (0,external_rxjs_namespaceObject.catchError)((err) => {
            // If the API call fails, we want to reset the stored email and prelogin data so that future calls will attempt to fetch again
            // otherwise, there isn't a way to recover from a failed API call since the failed result would be cached indefinitely
            this.currentEmail = null;
            this.currentPreloginData$ = null;
            throw err;
        }), (0,external_rxjs_namespaceObject.shareReplay)({ bufferSize: 1, refCount: false }));
        return this.currentPreloginData$;
    }
    clearCache() {
        this.currentEmail = null;
        this.currentPreloginData$ = null;
    }
}

;// ../../libs/common/src/auth/password-prelogin/password-prelogin.response.ts

class PasswordPreloginResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.kdf = this.getResponseProperty("Kdf");
        this.kdfIterations = this.getResponseProperty("KdfIterations");
        this.kdfMemory = this.getResponseProperty("KdfMemory");
        this.kdfParallelism = this.getResponseProperty("KdfParallelism");
    }
}

;// ../../libs/common/src/auth/password-prelogin/password-prelogin-api.service.ts
var password_prelogin_api_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};


class PasswordPreloginApiService {
    constructor(apiService, environmentService) {
        this.apiService = apiService;
        this.environmentService = environmentService;
    }
    getPreloginData(request) {
        return password_prelogin_api_service_awaiter(this, void 0, void 0, function* () {
            const env = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.environmentService.environment$);
            const r = yield this.apiService.send("POST", "/accounts/prelogin/password", request, false, true, env.getIdentityUrl());
            return new PasswordPreloginResponse(r);
        });
    }
}

;// ../../libs/common/src/auth/password-prelogin/index.ts





;// ../../libs/common/src/auth/services/auth.service.ts
var auth_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore



class AuthService {
    constructor(accountService, messageSender, keyService, apiService, stateService, tokenService) {
        this.accountService = accountService;
        this.messageSender = messageSender;
        this.keyService = keyService;
        this.apiService = apiService;
        this.stateService = stateService;
        this.tokenService = tokenService;
        this.activeAccountStatus$ = this.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.map)((account) => account === null || account === void 0 ? void 0 : account.id), (0,external_rxjs_namespaceObject.switchMap)((userId) => {
            return this.authStatusFor$(userId);
        }));
        this.authStatuses$ = this.accountService.accounts$.pipe((0,external_rxjs_namespaceObject.map)((accounts) => Object.keys(accounts)), (0,external_rxjs_namespaceObject.switchMap)((entries) => {
            if (entries.length === 0) {
                return (0,external_rxjs_namespaceObject.of)([]);
            }
            return (0,external_rxjs_namespaceObject.combineLatest)(entries.map((userId) => this.authStatusFor$(userId).pipe((0,external_rxjs_namespaceObject.map)((status) => ({ userId, status })))));
        }), (0,external_rxjs_namespaceObject.map)((statuses) => {
            return statuses.reduce((acc, { userId, status }) => {
                acc[userId] = status;
                return acc;
            }, {});
        }));
    }
    authStatusFor$(userId) {
        if (!utils_Utils.isGuid(userId)) {
            return (0,external_rxjs_namespaceObject.of)(authentication_status_AuthenticationStatus.LoggedOut);
        }
        return (0,external_rxjs_namespaceObject.combineLatest)([
            this.keyService.getInMemoryUserKeyFor$(userId),
            this.tokenService.hasAccessToken$(userId),
        ]).pipe((0,external_rxjs_namespaceObject.map)(([userKey, hasAccessToken]) => {
            if (!hasAccessToken) {
                return authentication_status_AuthenticationStatus.LoggedOut;
            }
            if (!userKey) {
                return authentication_status_AuthenticationStatus.Locked;
            }
            return authentication_status_AuthenticationStatus.Unlocked;
        }), (0,external_rxjs_namespaceObject.distinctUntilChanged)(), (0,external_rxjs_namespaceObject.shareReplay)({ bufferSize: 1, refCount: false }));
    }
    getAuthStatus(userId) {
        return auth_service_awaiter(this, void 0, void 0, function* () {
            userId !== null && userId !== void 0 ? userId : (userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.map)((a) => a === null || a === void 0 ? void 0 : a.id))));
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.authStatusFor$(userId));
        });
    }
    logOut(callback, userId) {
        callback();
        this.messageSender.send("loggedOut", { userId });
    }
}

;// ../../libs/common/src/models/request/update-avatar.request.ts
class UpdateAvatarRequest {
    constructor(avatarColor) {
        this.avatarColor = avatarColor;
    }
}

;// ../../libs/common/src/auth/services/avatar.service.ts
var avatar_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};


const AVATAR_COLOR = new UserKeyDefinition(AVATAR_DISK, "avatarColor", {
    deserializer: (value) => value,
    clearOn: [],
});
class AvatarService {
    constructor(apiService, stateProvider) {
        this.apiService = apiService;
        this.stateProvider = stateProvider;
        this.avatarColor$ = this.stateProvider.getActive(AVATAR_COLOR).state$;
    }
    setAvatarColor(color) {
        return avatar_service_awaiter(this, void 0, void 0, function* () {
            const { avatarColor } = yield this.apiService.putAvatar(new UpdateAvatarRequest(color));
            yield this.stateProvider.setUserState(AVATAR_COLOR, avatarColor);
        });
    }
    setSyncAvatarColor(userId, color) {
        return avatar_service_awaiter(this, void 0, void 0, function* () {
            yield this.stateProvider.getUser(userId, AVATAR_COLOR).update(() => color);
        });
    }
    getUserAvatarColor$(userId) {
        return this.stateProvider.getUser(userId, AVATAR_COLOR).state$;
    }
}

;// ../../libs/common/src/auth/services/default-active-user.accessor.ts

/**
 * Implementation for Platform so they can avoid a direct dependency on AccountService. Not for general consumption.
 */
class DefaultActiveUserAccessor {
    constructor(accountService) {
        this.accountService = accountService;
        this.activeUserId$ = this.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.map)((a) => (a != null ? a.id : null)));
    }
}

;// ../../libs/common/src/auth/abstractions/devices/responses/device.response.ts

class DeviceResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.id = this.getResponseProperty("Id");
        this.userId = this.getResponseProperty("UserId");
        this.name = this.getResponseProperty("Name");
        this.identifier = this.getResponseProperty("Identifier");
        this.type = this.getResponseProperty("Type");
        this.creationDate = this.getResponseProperty("CreationDate");
        this.revisionDate = this.getResponseProperty("RevisionDate");
        this.isTrusted = this.getResponseProperty("IsTrusted");
        this.encryptedUserKey = this.getResponseProperty("EncryptedUserKey");
        this.encryptedPublicKey = this.getResponseProperty("EncryptedPublicKey");
        this.devicePendingAuthRequest = this.getResponseProperty("DevicePendingAuthRequest");
        this.lastActivityDate = this.getResponseProperty("LastActivityDate");
    }
}

;// ../../libs/common/src/auth/models/request/untrust-devices.request.ts
class UntrustDevicesRequestModel {
    constructor(devices) {
        this.devices = devices;
    }
}

;// ../../libs/common/src/key-management/keys/models/rotateable-key-set.ts
/**
 * A set of keys where a symmetric `DownstreamKey` is protected by an encrypted public/private key-pair.
 * The `DownstreamKey` is used to encrypt/decrypt data, while the public/private key-pair is
 * used to rotate the `DownstreamKey`.
 *
 * The `PrivateKey` is protected by an `UpstreamKey`, such as a `DeviceKey`, or `PrfKey`,
 * and the `PublicKey` is protected by the `DownstreamKey`. This setup allows:
 *
 *   - Access to `DownstreamKey` by knowing the `UpstreamKey`
 *   - Rotation to a new `DownstreamKey` by knowing the current `DownstreamKey`,
 *     without needing access to the `UpstreamKey`
 */
class RotateableKeySet {
    constructor(
    /** `DownstreamKey` protected by publicKey */
    encapsulatedDownstreamKey, 
    /** DownstreamKey encrypted PublicKey */
    encryptedPublicKey, 
    /** UpstreamKey encrypted PrivateKey */
    encryptedPrivateKey) {
        this.encapsulatedDownstreamKey = encapsulatedDownstreamKey;
        this.encryptedPublicKey = encryptedPublicKey;
        this.encryptedPrivateKey = encryptedPrivateKey;
    }
}

;// ../../libs/common/src/auth/models/response/protected-device.response.ts



class ProtectedDeviceResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.id = this.getResponseProperty("id");
        this.name = this.getResponseProperty("name");
        this.identifier = this.getResponseProperty("identifier");
        this.type = this.getResponseProperty("type");
        this.creationDate = new Date(this.getResponseProperty("creationDate"));
        if (response.encryptedUserKey) {
            this.encryptedUserKey = new enc_string_EncString(this.getResponseProperty("encryptedUserKey"));
        }
        if (response.encryptedPublicKey) {
            this.encryptedPublicKey = new enc_string_EncString(this.getResponseProperty("encryptedPublicKey"));
        }
    }
    getRotateableKeyset() {
        return new RotateableKeySet(this.encryptedUserKey, this.encryptedPublicKey);
    }
    isTrusted() {
        return this.encryptedUserKey != null && this.encryptedPublicKey != null;
    }
}

;// ../../libs/common/src/auth/services/devices/requests/trusted-device-keys.request.ts
class TrustedDeviceKeysRequest {
    constructor(encryptedUserKey, encryptedPublicKey, encryptedPrivateKey) {
        this.encryptedUserKey = encryptedUserKey;
        this.encryptedPublicKey = encryptedPublicKey;
        this.encryptedPrivateKey = encryptedPrivateKey;
    }
}

;// ../../libs/common/src/auth/services/devices-api.service.implementation.ts
var devices_api_service_implementation_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};






class DevicesApiServiceImplementation {
    constructor(apiService) {
        this.apiService = apiService;
    }
    getKnownDevice(email, deviceIdentifier) {
        return devices_api_service_implementation_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("GET", "/devices/knowndevice", null, false, true, null, (headers) => {
                headers.set("X-Device-Identifier", deviceIdentifier);
                headers.set("X-Request-Email", utils_Utils.fromUtf8ToUrlB64(email));
            });
            return r;
        });
    }
    /**
     * Get device by identifier
     * @param deviceIdentifier - client generated id (not device id in DB)
     */
    getDeviceByIdentifier(deviceIdentifier) {
        return devices_api_service_implementation_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("GET", `/devices/identifier/${deviceIdentifier}`, null, true, true);
            return new DeviceResponse(r);
        });
    }
    getDevices() {
        return devices_api_service_implementation_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("GET", "/devices", null, true, true, null);
            return new ListResponse(r, DeviceResponse);
        });
    }
    updateTrustedDeviceKeys(deviceIdentifier, devicePublicKeyEncryptedUserKey, userKeyEncryptedDevicePublicKey, deviceKeyEncryptedDevicePrivateKey) {
        return devices_api_service_implementation_awaiter(this, void 0, void 0, function* () {
            const request = new TrustedDeviceKeysRequest(devicePublicKeyEncryptedUserKey, userKeyEncryptedDevicePublicKey, deviceKeyEncryptedDevicePrivateKey);
            const result = yield this.apiService.send("PUT", `/devices/${deviceIdentifier}/keys`, request, true, true);
            return new DeviceResponse(result);
        });
    }
    updateTrust(updateDevicesTrustRequestModel, deviceIdentifier) {
        return devices_api_service_implementation_awaiter(this, void 0, void 0, function* () {
            yield this.apiService.send("POST", "/devices/update-trust", updateDevicesTrustRequestModel, true, false, null, (headers) => {
                headers.set("Device-Identifier", deviceIdentifier);
            });
        });
    }
    getDeviceKeys(deviceIdentifier) {
        return devices_api_service_implementation_awaiter(this, void 0, void 0, function* () {
            const result = yield this.apiService.send("POST", `/devices/${deviceIdentifier}/retrieve-keys`, null, true, true);
            return new ProtectedDeviceResponse(result);
        });
    }
    postDeviceTrustLoss(deviceIdentifier) {
        return devices_api_service_implementation_awaiter(this, void 0, void 0, function* () {
            yield this.apiService.send("POST", "/devices/lost-trust", null, true, false, null, (headers) => {
                headers.set("Device-Identifier", deviceIdentifier);
            });
        });
    }
    deactivateDevice(deviceId) {
        return devices_api_service_implementation_awaiter(this, void 0, void 0, function* () {
            yield this.apiService.send("POST", `/devices/${deviceId}/deactivate`, null, true, false);
        });
    }
    untrustDevices(deviceIds) {
        return devices_api_service_implementation_awaiter(this, void 0, void 0, function* () {
            yield this.apiService.send("POST", "/devices/untrust", new UntrustDevicesRequestModel(deviceIds), true, false);
        });
    }
}

;// ../../libs/common/src/auth/services/master-password/master-password-api.service.implementation.ts
var master_password_api_service_implementation_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
class MasterPasswordApiService {
    constructor(apiService, logService) {
        this.apiService = apiService;
        this.logService = logService;
    }
    setPassword(request) {
        return master_password_api_service_implementation_awaiter(this, void 0, void 0, function* () {
            try {
                const response = yield this.apiService.send("POST", "/accounts/set-password", request, true, false);
                return response;
            }
            catch (e) {
                this.logService.error(e);
                throw e;
            }
        });
    }
    postPassword(request) {
        return master_password_api_service_implementation_awaiter(this, void 0, void 0, function* () {
            try {
                const response = yield this.apiService.send("POST", "/accounts/password", request, true, false);
                return response;
            }
            catch (e) {
                this.logService.error(e);
                throw e;
            }
        });
    }
    putUpdateTempPassword(request) {
        return master_password_api_service_implementation_awaiter(this, void 0, void 0, function* () {
            try {
                const response = yield this.apiService.send("PUT", "/accounts/update-temp-password", request, true, false);
                return response;
            }
            catch (e) {
                this.logService.error(e);
                throw e;
            }
        });
    }
    putUpdateTdeOffboardingPassword(request) {
        return master_password_api_service_implementation_awaiter(this, void 0, void 0, function* () {
            try {
                const response = yield this.apiService.send("PUT", "/accounts/update-tde-offboarding-password", request, true, false);
                return response;
            }
            catch (e) {
                this.logService.error(e);
                throw e;
            }
        });
    }
}

;// ../../libs/common/src/auth/models/domain/set-tokens-result.ts
class SetTokensResult {
    constructor(accessToken, refreshToken, clientIdSecretPair) {
        this.accessToken = accessToken;
        this.refreshToken = refreshToken;
        this.clientIdSecretPair = clientIdSecretPair;
    }
}

;// ../../libs/common/src/auth/services/token.state.ts

// Note: all tokens / API key information must be cleared on logout.
// because we are using secure storage, we must manually call to clean up our tokens.
// See stateService.deAuthenticateAccount for where we call clearTokens(...)
const token_state_ACCESS_TOKEN_DISK = new UserKeyDefinition(TOKEN_DISK, "accessToken", {
    deserializer: (accessToken) => accessToken,
    clearOn: [], // Manually handled
});
const ACCESS_TOKEN_MEMORY = new UserKeyDefinition(TOKEN_MEMORY, "accessToken", {
    deserializer: (accessToken) => accessToken,
    clearOn: [], // Manually handled
});
const token_state_REFRESH_TOKEN_DISK = new UserKeyDefinition(TOKEN_DISK, "refreshToken", {
    deserializer: (refreshToken) => refreshToken,
    clearOn: [], // Manually handled
});
const REFRESH_TOKEN_MEMORY = new UserKeyDefinition(TOKEN_MEMORY, "refreshToken", {
    deserializer: (refreshToken) => refreshToken,
    clearOn: [], // Manually handled
});
const token_state_EMAIL_TWO_FACTOR_TOKEN_RECORD_DISK_LOCAL = KeyDefinition.record(TOKEN_DISK_LOCAL, "emailTwoFactorTokenRecord", {
    deserializer: (emailTwoFactorTokenRecord) => emailTwoFactorTokenRecord,
});
const token_state_API_KEY_CLIENT_ID_DISK = new UserKeyDefinition(TOKEN_DISK, "apiKeyClientId", {
    deserializer: (apiKeyClientId) => apiKeyClientId,
    clearOn: [], // Manually handled
});
const API_KEY_CLIENT_ID_MEMORY = new UserKeyDefinition(TOKEN_MEMORY, "apiKeyClientId", {
    deserializer: (apiKeyClientId) => apiKeyClientId,
    clearOn: [], // Manually handled
});
const token_state_API_KEY_CLIENT_SECRET_DISK = new UserKeyDefinition(TOKEN_DISK, "apiKeyClientSecret", {
    deserializer: (apiKeyClientSecret) => apiKeyClientSecret,
    clearOn: [], // Manually handled
});
const API_KEY_CLIENT_SECRET_MEMORY = new UserKeyDefinition(TOKEN_MEMORY, "apiKeyClientSecret", {
    deserializer: (apiKeyClientSecret) => apiKeyClientSecret,
    clearOn: [], // Manually handled
});
const SECURITY_STAMP_MEMORY = new UserKeyDefinition(TOKEN_MEMORY, "securityStamp", {
    deserializer: (securityStamp) => securityStamp,
    clearOn: ["logout"],
});

;// ../../libs/common/src/auth/services/token.service.ts
var token_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop.
// eslint-disable-next-line no-restricted-imports









// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var TokenStorageLocation;
(function (TokenStorageLocation) {
    TokenStorageLocation["Disk"] = "disk";
    TokenStorageLocation["SecureStorage"] = "secureStorage";
    TokenStorageLocation["Memory"] = "memory";
})(TokenStorageLocation || (TokenStorageLocation = {}));
class TokenService {
    constructor(
    // Note: we cannot use ActiveStateProvider because if we ever want to inject
    // this service into the AccountService, we will make a circular dependency
    singleUserStateProvider, globalStateProvider, platformSupportsSecureStorage, secureStorageService, keyGenerationService, encryptService, logService, logoutCallback) {
        this.singleUserStateProvider = singleUserStateProvider;
        this.globalStateProvider = globalStateProvider;
        this.platformSupportsSecureStorage = platformSupportsSecureStorage;
        this.secureStorageService = secureStorageService;
        this.keyGenerationService = keyGenerationService;
        this.encryptService = encryptService;
        this.logService = logService;
        this.logoutCallback = logoutCallback;
        this.accessTokenKeySecureStorageKey = "_accessTokenKey";
        this.refreshTokenSecureStorageKey = "_refreshToken";
        this.initializeState();
    }
    hasAccessToken$(userId) {
        // FIXME Once once vault timeout action is observable, we can use it to determine storage location
        // and avoid the need to check both disk and memory.
        return (0,external_rxjs_namespaceObject.combineLatest)([
            this.singleUserStateProvider.get(userId, token_state_ACCESS_TOKEN_DISK).state$,
            this.singleUserStateProvider.get(userId, ACCESS_TOKEN_MEMORY).state$,
        ]).pipe((0,external_rxjs_namespaceObject.map)(([disk, memory]) => Boolean(disk || memory)));
    }
    initializeState() {
        this.emailTwoFactorTokenRecordGlobalState = this.globalStateProvider.get(token_state_EMAIL_TWO_FACTOR_TOKEN_RECORD_DISK_LOCAL);
        this.activeUserIdGlobalState = this.globalStateProvider.get(account_service_ACCOUNT_ACTIVE_ACCOUNT_ID);
    }
    setTokens(accessToken, vaultTimeoutAction, vaultTimeout, refreshToken, clientIdClientSecret) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            if (!accessToken) {
                throw new Error("Access token is required.");
            }
            // Can't check for falsey b/c 0 is a valid value
            if (vaultTimeout == null) {
                throw new Error("Vault Timeout is required.");
            }
            if (vaultTimeoutAction == null) {
                throw new Error("Vault Timeout Action is required.");
            }
            // get user id the access token
            const userId = yield this.getUserIdFromAccessToken(accessToken);
            if (!userId) {
                throw new Error("User id not found. Cannot set tokens.");
            }
            const newAccessToken = yield this._setAccessToken(accessToken, vaultTimeoutAction, vaultTimeout, userId);
            const newTokens = new SetTokensResult(newAccessToken);
            if (refreshToken) {
                newTokens.refreshToken = yield this.setRefreshToken(refreshToken, vaultTimeoutAction, vaultTimeout, userId);
            }
            if (clientIdClientSecret != null) {
                const clientId = yield this.setClientId(clientIdClientSecret[0], vaultTimeoutAction, vaultTimeout, userId);
                const clientSecret = yield this.setClientSecret(clientIdClientSecret[1], vaultTimeoutAction, vaultTimeout, userId);
                newTokens.clientIdSecretPair = [clientId, clientSecret];
            }
            return newTokens;
        });
    }
    getAccessTokenKey(userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            const accessTokenKeyB64 = yield this.secureStorageService.get(`${userId}${this.accessTokenKeySecureStorageKey}`, this.getSecureStorageOptions(userId));
            if (!accessTokenKeyB64) {
                return null;
            }
            const accessTokenKey = SymmetricCryptoKey.fromJSON(accessTokenKeyB64);
            return accessTokenKey;
        });
    }
    createAndSaveAccessTokenKey(userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            const newAccessTokenKey = (yield this.keyGenerationService.createKey(512));
            yield this.secureStorageService.save(`${userId}${this.accessTokenKeySecureStorageKey}`, newAccessTokenKey, this.getSecureStorageOptions(userId));
            // We are having intermittent issues with access token keys not saving into secure storage on windows 10/11.
            // So, let's add a check to ensure we can read the value after writing it.
            const accessTokenKey = yield this.getAccessTokenKey(userId);
            if (!accessTokenKey) {
                throw new Error("New Access token key unable to be retrieved from secure storage.");
            }
            return newAccessTokenKey;
        });
    }
    clearAccessTokenKey(userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            yield this.secureStorageService.remove(`${userId}${this.accessTokenKeySecureStorageKey}`, this.getSecureStorageOptions(userId));
        });
    }
    getOrCreateAccessTokenKey(userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            if (!this.platformSupportsSecureStorage) {
                throw new Error("Platform does not support secure storage. Cannot obtain access token key.");
            }
            if (!userId) {
                throw new Error("User id not found. Cannot obtain access token key.");
            }
            // First see if we have an accessTokenKey in secure storage and return it if we do
            // Note: retrieving/saving data from/to secure storage on linux will throw if the
            // distro doesn't have a secure storage provider
            let accessTokenKey = yield this.getAccessTokenKey(userId);
            if (!accessTokenKey) {
                // Otherwise, create a new one and save it to secure storage, then return it
                accessTokenKey = yield this.createAndSaveAccessTokenKey(userId);
            }
            return accessTokenKey;
        });
    }
    encryptAccessToken(accessToken, userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            const accessTokenKey = yield this.getOrCreateAccessTokenKey(userId);
            return yield this.encryptService.encryptString(accessToken, accessTokenKey);
        });
    }
    /**
     * Decrypts the access token using the provided access token key.
     *
     * @param accessTokenKey - the key used to decrypt the access token
     * @param encryptedAccessToken - the encrypted access token to decrypt
     * @returns the decrypted access token
     * @throws Error if the access token key is not provided or the decryption fails
     */
    decryptAccessToken(accessTokenKey, encryptedAccessToken) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            if (!accessTokenKey) {
                throw new Error("decryptAccessToken: Access token key required. Cannot decrypt access token.");
            }
            try {
                const decryptedAccessToken = yield this.encryptService.decryptString(encryptedAccessToken, accessTokenKey);
                return decryptedAccessToken;
            }
            catch (e) {
                // Note: This should be replaced by the owning team with appropriate, domain-specific behavior.
                this.logService.error("[TokenService] Error decrypting access token", e);
                throw e;
            }
        });
    }
    /**
     * Internal helper for set access token which always requires user id.
     * This is useful because setTokens always will have a user id from the access token whereas
     * the public setAccessToken method does not.
     */
    _setAccessToken(accessToken, vaultTimeoutAction, vaultTimeout, userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            const storageLocation = yield this.determineStorageLocation(vaultTimeoutAction, vaultTimeout, true);
            switch (storageLocation) {
                case TokenStorageLocation.SecureStorage: {
                    // Secure storage implementations have variable length limitations (Windows), so we cannot
                    // store the access token directly. Instead, we encrypt with accessTokenKey and store that
                    // in secure storage.
                    let decryptedAccessToken = null;
                    try {
                        const encryptedAccessToken = yield this.encryptAccessToken(accessToken, userId);
                        // Save the encrypted access token to disk
                        yield this.singleUserStateProvider
                            .get(userId, token_state_ACCESS_TOKEN_DISK)
                            .update((_) => encryptedAccessToken.encryptedString, {
                            shouldUpdate: (previousValue) => previousValue !== encryptedAccessToken.encryptedString,
                        });
                        // If we've successfully stored the encrypted access token to disk, we can return the decrypted access token
                        // so that the caller can use it immediately.
                        decryptedAccessToken = accessToken;
                        // Then, we can clear the memory state location to enforce that a single location holds the access token at a time.
                        yield this.clearAccessTokenMemoryLocation(userId);
                    }
                    catch (error) {
                        this.logService.error(`SetAccessToken: storing encrypted access token in secure storage failed. Falling back to disk storage.`, error);
                        // Fall back to disk storage for unecrypted access token
                        decryptedAccessToken = yield this.singleUserStateProvider
                            .get(userId, token_state_ACCESS_TOKEN_DISK)
                            .update((_) => accessToken, {
                            shouldUpdate: (previousValue) => previousValue !== accessToken,
                        });
                        // Then, we can clear the memory state location to enforce that a single location holds the access token at a time.
                        yield this.clearAccessTokenMemoryLocation(userId);
                    }
                    return decryptedAccessToken;
                }
                case TokenStorageLocation.Disk: {
                    // Access token stored on disk unencrypted as platform does not support secure storage
                    const newAccessToken = yield this.singleUserStateProvider
                        .get(userId, token_state_ACCESS_TOKEN_DISK)
                        .update((_) => accessToken, {
                        shouldUpdate: (previousValue) => previousValue !== accessToken,
                    });
                    // Then, we can clear the memory state location to enforce that a single location holds the access token at a time.
                    yield this.clearAccessTokenMemoryLocation(userId);
                    return newAccessToken;
                }
                case TokenStorageLocation.Memory: {
                    // Access token stored in memory due to vault timeout settings
                    const newAccessToken = yield this.singleUserStateProvider
                        .get(userId, ACCESS_TOKEN_MEMORY)
                        .update((_) => accessToken);
                    // Then, we can clear the disk state location to enforce that a single location holds the access token at a time.
                    yield this.clearAccessTokenDiskLocation(userId);
                    return newAccessToken;
                }
            }
        });
    }
    setAccessToken(accessToken, vaultTimeoutAction, vaultTimeout) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            if (!accessToken) {
                throw new Error("Access token is required.");
            }
            const userId = yield this.getUserIdFromAccessToken(accessToken);
            // If we don't have a user id, we can't save the value
            if (!userId) {
                throw new Error("User id not found. Cannot save access token.");
            }
            // Can't check for falsey b/c 0 is a valid value
            if (vaultTimeout == null) {
                throw new Error("Vault Timeout is required.");
            }
            if (vaultTimeoutAction == null) {
                throw new Error("Vault Timeout Action is required.");
            }
            return yield this._setAccessToken(accessToken, vaultTimeoutAction, vaultTimeout, userId);
        });
    }
    clearAccessToken(userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            userId !== null && userId !== void 0 ? userId : (userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.activeUserIdGlobalState.state$));
            // If we don't have a user id, we can't clear the value
            if (!userId) {
                throw new Error("User id not found. Cannot clear access token.");
            }
            // TODO: re-eval this implementation once we get shared key definitions for vault timeout and vault timeout action data.
            // we can't determine storage location w/out vaultTimeoutAction and vaultTimeout
            // but we can simply clear all locations to avoid the need to require those parameters.
            // When secure storage is supported, clear the encryption key from secure storage.
            // When not supported (e.g., portable builds), tokens are stored on disk and this step is skipped.
            if (this.platformSupportsSecureStorage) {
                // Always clear the access token key when clearing the access token.
                // The next set of the access token will create a new access token key.
                yield this.clearAccessTokenKey(userId);
            }
            // Clear from disk and memory.
            yield this.clearAccessTokenDiskLocation(userId);
            yield this.clearAccessTokenMemoryLocation(userId);
        });
    }
    clearAccessTokenMemoryLocation(userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            yield this.singleUserStateProvider.get(userId, ACCESS_TOKEN_MEMORY).update((_) => null);
        });
    }
    clearAccessTokenDiskLocation(userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            yield this.singleUserStateProvider.get(userId, token_state_ACCESS_TOKEN_DISK).update((_) => null, {
                shouldUpdate: (previousValue) => previousValue !== null,
            });
        });
    }
    getAccessToken(userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            if (!userId) {
                return null;
            }
            // Try to get the access token from memory
            const accessTokenMemory = yield this.getStateValueByUserIdAndKeyDef(userId, ACCESS_TOKEN_MEMORY);
            if (accessTokenMemory != null) {
                return accessTokenMemory;
            }
            // If memory is null, read from disk
            const accessTokenDisk = yield this.getStateValueByUserIdAndKeyDef(userId, token_state_ACCESS_TOKEN_DISK);
            if (!accessTokenDisk) {
                return null;
            }
            // When platformSupportsSecureStorage=true, tokens on disk are encrypted and require
            // decryption keys from secure storage. When false (e.g., portable builds), tokens are
            // stored on disk.
            if (this.platformSupportsSecureStorage) {
                let accessTokenKey;
                try {
                    accessTokenKey = yield this.getAccessTokenKey(userId);
                }
                catch (error) {
                    if (enc_string_EncString.isSerializedEncString(accessTokenDisk)) {
                        this.logService.error("Access token key retrieval failed. Unable to decrypt encrypted access token. Logging user out.", error);
                        yield this.logoutCallback("accessTokenUnableToBeDecrypted", userId);
                        return null;
                    }
                    // If the access token key is not found, but the access token is unencrypted then
                    // this indicates that this is the pre-migration state where the access token
                    // was stored unencrypted on disk. We can return the access token as is.
                    // Note: this is likely to only be hit for linux users who don't
                    // have a secure storage provider configured.
                    return accessTokenDisk;
                }
                if (!accessTokenKey) {
                    if (enc_string_EncString.isSerializedEncString(accessTokenDisk)) {
                        // The access token is encrypted but we don't have the key to decrypt it for
                        // whatever reason so we have to log the user out.
                        this.logService.error("Access token key not found to decrypt encrypted access token. Logging user out.");
                        yield this.logoutCallback("accessTokenUnableToBeDecrypted", userId);
                        return null;
                    }
                    // We know this is an unencrypted access token
                    return accessTokenDisk;
                }
                try {
                    const encryptedAccessTokenEncString = new enc_string_EncString(accessTokenDisk);
                    const decryptedAccessToken = yield this.decryptAccessToken(accessTokenKey, encryptedAccessTokenEncString);
                    return decryptedAccessToken;
                }
                catch (error) {
                    // If an error occurs during decryption, logout and then return null.
                    // We don't try to recover here since we'd like to know
                    // if access token and key are getting out of sync.
                    this.logService.error(`Failed to decrypt access token`, error);
                    yield this.logoutCallback("accessTokenUnableToBeDecrypted", userId);
                    return null;
                }
            }
            return accessTokenDisk;
        });
    }
    // Private because we only ever set the refresh token when also setting the access token
    // and we need the user id from the access token to save to secure storage
    setRefreshToken(refreshToken, vaultTimeoutAction, vaultTimeout, userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            // If we don't have a user id, we can't save the value
            if (!userId) {
                throw new Error("User id not found. Cannot save refresh token.");
            }
            // Can't check for falsey b/c 0 is a valid value
            if (vaultTimeout == null) {
                throw new Error("Vault Timeout is required.");
            }
            if (vaultTimeoutAction == null) {
                throw new Error("Vault Timeout Action is required.");
            }
            const storageLocation = yield this.determineStorageLocation(vaultTimeoutAction, vaultTimeout, true);
            switch (storageLocation) {
                case TokenStorageLocation.SecureStorage: {
                    let decryptedRefreshToken = null;
                    try {
                        yield this.saveStringToSecureStorage(userId, this.refreshTokenSecureStorageKey, refreshToken);
                        // Check if the refresh token was able to be saved to secure storage by reading it
                        // immediately after setting it. This is needed due to intermittent silent failures on Windows 10/11.
                        const refreshTokenSecureStorage = yield this.getStringFromSecureStorage(userId, this.refreshTokenSecureStorageKey);
                        // Only throw if the refresh token was not saved to secure storage
                        // If we only check for a nullish value out of secure storage without considering the input value,
                        // then we would end up falling back to disk storage if the input value was null.
                        if (refreshToken !== null && !refreshTokenSecureStorage) {
                            throw new Error("Refresh token failed to save to secure storage.");
                        }
                        // If we've successfully stored the encrypted refresh token, we can return the decrypted refresh token
                        // so that the caller can use it immediately.
                        decryptedRefreshToken = refreshToken;
                        yield this.clearRefreshTokenDiskLocation(userId);
                        yield this.clearRefreshTokenMemoryLocation(userId);
                    }
                    catch (error) {
                        // This case could be hit for both Linux users who don't have secure storage configured
                        // or for Windows users who have intermittent issues with secure storage.
                        this.logService.error(`SetRefreshToken: storing refresh token in secure storage failed. Falling back to disk storage.`, error);
                        // Fall back to disk storage for refresh token
                        decryptedRefreshToken = yield this.singleUserStateProvider
                            .get(userId, token_state_REFRESH_TOKEN_DISK)
                            .update((_) => refreshToken, {
                            shouldUpdate: (previousValue) => previousValue !== refreshToken,
                        });
                        yield this.clearRefreshTokenMemoryLocation(userId);
                    }
                    return decryptedRefreshToken;
                }
                case TokenStorageLocation.Disk: {
                    const newRefreshToken = yield this.singleUserStateProvider
                        .get(userId, token_state_REFRESH_TOKEN_DISK)
                        .update((_) => refreshToken, {
                        shouldUpdate: (previousValue) => previousValue !== refreshToken,
                    });
                    yield this.clearRefreshTokenMemoryLocation(userId);
                    return newRefreshToken;
                }
                case TokenStorageLocation.Memory: {
                    const newRefreshToken = yield this.singleUserStateProvider
                        .get(userId, REFRESH_TOKEN_MEMORY)
                        .update((_) => refreshToken);
                    yield this.clearRefreshTokenDiskLocation(userId);
                    return newRefreshToken;
                }
            }
        });
    }
    getRefreshToken(userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            if (!userId) {
                return null;
            }
            // pre-secure storage migration:
            // Always read memory first b/c faster
            const refreshTokenMemory = yield this.getStateValueByUserIdAndKeyDef(userId, REFRESH_TOKEN_MEMORY);
            if (refreshTokenMemory != null) {
                return refreshTokenMemory;
            }
            // if memory is null, read from disk and then secure storage
            const refreshTokenDisk = yield this.getStateValueByUserIdAndKeyDef(userId, token_state_REFRESH_TOKEN_DISK);
            if (refreshTokenDisk != null) {
                // This handles the scenario pre-secure storage migration where the refresh token was stored on disk.
                return refreshTokenDisk;
            }
            if (this.platformSupportsSecureStorage) {
                try {
                    const refreshTokenSecureStorage = yield this.getStringFromSecureStorage(userId, this.refreshTokenSecureStorageKey);
                    if (refreshTokenSecureStorage != null) {
                        return refreshTokenSecureStorage;
                    }
                    this.logService.error("Refresh token not found in secure storage. Access token will fail to refresh upon expiration or manual refresh.");
                }
                catch (error) {
                    // This case will be hit for Linux users who don't have secure storage configured.
                    this.logService.error(`Failed to retrieve refresh token from secure storage`, error);
                    yield this.logoutCallback("refreshTokenSecureStorageRetrievalFailure", userId);
                }
            }
            return null;
        });
    }
    clearRefreshToken(userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            // If we don't have a user id, we can't clear the value
            if (!userId) {
                throw new Error("User id not found. Cannot clear refresh token.");
            }
            // TODO: re-eval this once we get shared key definitions for vault timeout and vault timeout action data.
            // we can't determine storage location w/out vaultTimeoutAction and vaultTimeout
            // but we can simply clear all locations to avoid the need to require those parameters
            if (this.platformSupportsSecureStorage) {
                yield this.secureStorageService.remove(`${userId}${this.refreshTokenSecureStorageKey}`, this.getSecureStorageOptions(userId));
            }
            // Platform doesn't support secure storage, so use state provider implementation
            yield this.clearRefreshTokenMemoryLocation(userId);
            yield this.clearRefreshTokenDiskLocation(userId);
        });
    }
    clearRefreshTokenMemoryLocation(userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            yield this.singleUserStateProvider.get(userId, REFRESH_TOKEN_MEMORY).update((_) => null);
        });
    }
    clearRefreshTokenDiskLocation(userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            yield this.singleUserStateProvider.get(userId, token_state_REFRESH_TOKEN_DISK).update((_) => null, {
                shouldUpdate: (previousValue) => previousValue !== null,
            });
        });
    }
    setClientId(clientId, vaultTimeoutAction, vaultTimeout, userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            userId !== null && userId !== void 0 ? userId : (userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.activeUserIdGlobalState.state$));
            // If we don't have a user id, we can't save the value
            if (!userId) {
                throw new Error("User id not found. Cannot save client id.");
            }
            // Can't check for falsey b/c 0 is a valid value
            if (vaultTimeout == null) {
                throw new Error("Vault Timeout is required.");
            }
            if (vaultTimeoutAction == null) {
                throw new Error("Vault Timeout Action is required.");
            }
            const storageLocation = yield this.determineStorageLocation(vaultTimeoutAction, vaultTimeout, false);
            if (storageLocation === TokenStorageLocation.Disk) {
                const newClientId = yield this.singleUserStateProvider
                    .get(userId, token_state_API_KEY_CLIENT_ID_DISK)
                    .update((_) => clientId);
                yield this.clearClientIdMemoryLocation(userId);
                return newClientId;
            }
            else if (storageLocation === TokenStorageLocation.Memory) {
                const newClientId = yield this.singleUserStateProvider
                    .get(userId, API_KEY_CLIENT_ID_MEMORY)
                    .update((_) => clientId);
                yield this.clearClientIdDiskLocation(userId);
                return newClientId;
            }
        });
    }
    getClientId(userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            if (!userId) {
                return undefined;
            }
            // Always read memory first b/c faster
            const apiKeyClientIdMemory = yield this.getStateValueByUserIdAndKeyDef(userId, API_KEY_CLIENT_ID_MEMORY);
            if (apiKeyClientIdMemory != null) {
                return apiKeyClientIdMemory;
            }
            // if memory is null, read from disk
            return yield this.getStateValueByUserIdAndKeyDef(userId, token_state_API_KEY_CLIENT_ID_DISK);
        });
    }
    clearClientId(userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            userId !== null && userId !== void 0 ? userId : (userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.activeUserIdGlobalState.state$));
            // If we don't have a user id, we can't clear the value
            if (!userId) {
                throw new Error("User id not found. Cannot clear client id.");
            }
            // TODO: re-eval this once we get shared key definitions for vault timeout and vault timeout action data.
            // we can't determine storage location w/out vaultTimeoutAction and vaultTimeout
            // but we can simply clear both locations to avoid the need to require those parameters
            yield this.clearClientIdMemoryLocation(userId);
            yield this.clearClientIdDiskLocation(userId);
        });
    }
    clearClientIdMemoryLocation(userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            yield this.singleUserStateProvider.get(userId, API_KEY_CLIENT_ID_MEMORY).update((_) => null);
        });
    }
    clearClientIdDiskLocation(userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            yield this.singleUserStateProvider.get(userId, token_state_API_KEY_CLIENT_ID_DISK).update((_) => null);
        });
    }
    setClientSecret(clientSecret, vaultTimeoutAction, vaultTimeout, userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            userId !== null && userId !== void 0 ? userId : (userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.activeUserIdGlobalState.state$));
            if (!userId) {
                throw new Error("User id not found. Cannot save client secret.");
            }
            // Can't check for falsey b/c 0 is a valid value
            if (vaultTimeout == null) {
                throw new Error("Vault Timeout is required.");
            }
            if (vaultTimeoutAction == null) {
                throw new Error("Vault Timeout Action is required.");
            }
            const storageLocation = yield this.determineStorageLocation(vaultTimeoutAction, vaultTimeout, false);
            if (storageLocation === TokenStorageLocation.Disk) {
                const newClientSecret = yield this.singleUserStateProvider
                    .get(userId, token_state_API_KEY_CLIENT_SECRET_DISK)
                    .update((_) => clientSecret);
                yield this.clearClientSecretMemoryLocation(userId);
                return newClientSecret;
            }
            else if (storageLocation === TokenStorageLocation.Memory) {
                const newClientSecret = yield this.singleUserStateProvider
                    .get(userId, API_KEY_CLIENT_SECRET_MEMORY)
                    .update((_) => clientSecret);
                yield this.clearClientSecretDiskLocation(userId);
                return newClientSecret;
            }
        });
    }
    getClientSecret(userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            if (!userId) {
                return undefined;
            }
            // Always read memory first b/c faster
            const apiKeyClientSecretMemory = yield this.getStateValueByUserIdAndKeyDef(userId, API_KEY_CLIENT_SECRET_MEMORY);
            if (apiKeyClientSecretMemory != null) {
                return apiKeyClientSecretMemory;
            }
            // if memory is null, read from disk
            return yield this.getStateValueByUserIdAndKeyDef(userId, token_state_API_KEY_CLIENT_SECRET_DISK);
        });
    }
    clearClientSecret(userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            userId !== null && userId !== void 0 ? userId : (userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.activeUserIdGlobalState.state$));
            // If we don't have a user id, we can't clear the value
            if (!userId) {
                throw new Error("User id not found. Cannot clear client secret.");
            }
            // TODO: re-eval this once we get shared key definitions for vault timeout and vault timeout action data.
            // we can't determine storage location w/out vaultTimeoutAction and vaultTimeout
            // but we can simply clear both locations to avoid the need to require those parameters
            yield this.clearClientSecretMemoryLocation(userId);
            yield this.clearClientSecretDiskLocation(userId);
        });
    }
    clearClientSecretMemoryLocation(userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            yield this.singleUserStateProvider
                .get(userId, API_KEY_CLIENT_SECRET_MEMORY)
                .update((_) => null);
        });
    }
    clearClientSecretDiskLocation(userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            yield this.singleUserStateProvider.get(userId, token_state_API_KEY_CLIENT_SECRET_DISK).update((_) => null);
        });
    }
    setTwoFactorToken(email, twoFactorToken) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            yield this.emailTwoFactorTokenRecordGlobalState.update((emailTwoFactorTokenRecord) => {
                emailTwoFactorTokenRecord !== null && emailTwoFactorTokenRecord !== void 0 ? emailTwoFactorTokenRecord : (emailTwoFactorTokenRecord = {});
                emailTwoFactorTokenRecord[email] = twoFactorToken;
                return emailTwoFactorTokenRecord;
            });
        });
    }
    getTwoFactorToken(email) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            const emailTwoFactorTokenRecord = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.emailTwoFactorTokenRecordGlobalState.state$);
            if (!emailTwoFactorTokenRecord) {
                return null;
            }
            return emailTwoFactorTokenRecord[email];
        });
    }
    clearTwoFactorToken(email) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            yield this.emailTwoFactorTokenRecordGlobalState.update((emailTwoFactorTokenRecord) => {
                emailTwoFactorTokenRecord !== null && emailTwoFactorTokenRecord !== void 0 ? emailTwoFactorTokenRecord : (emailTwoFactorTokenRecord = {});
                delete emailTwoFactorTokenRecord[email];
                return emailTwoFactorTokenRecord;
            });
        });
    }
    // TODO: stop accepting optional userIds
    clearTokens(userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            userId !== null && userId !== void 0 ? userId : (userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.activeUserIdGlobalState.state$));
            if (!userId) {
                throw new Error("User id not found. Cannot clear tokens.");
            }
            yield Promise.all([
                this.clearAccessToken(userId),
                this.clearRefreshToken(userId),
                this.clearClientId(userId),
                this.clearClientSecret(userId),
            ]);
        });
    }
    cleanupTokenStorage(userIds) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            for (const userId of userIds) {
                const accessToken = yield this.getAccessToken(userId);
                if (accessToken == null) {
                    yield this.clearTokens(userId);
                }
            }
        });
    }
    // jwthelper methods
    // ref https://github.com/auth0/angular-jwt/blob/master/src/angularJwt/services/jwt.js
    decodeAccessToken(tokenOrUserId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            let token = tokenOrUserId;
            if (utils_Utils.isGuid(tokenOrUserId)) {
                token = yield this.getAccessToken(tokenOrUserId);
            }
            else {
                token !== null && token !== void 0 ? token : (token = yield this.getAccessToken(yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.activeUserIdGlobalState.state$)));
            }
            if (token == null) {
                throw new Error("Access token not found.");
            }
            return decodeJwtTokenToJson(token);
        });
    }
    // TODO: PM-6678- tech debt - consider consolidating the return types of all these access
    // token data retrieval methods to return null if something goes wrong instead of throwing an error.
    getTokenExpirationDate(userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            let decoded;
            try {
                decoded = yield this.decodeAccessToken(userId);
            }
            catch (error) {
                throw new Error("Failed to decode access token: " + error.message);
            }
            // per RFC, exp claim is optional but if it exists, it should be a number
            if (!decoded || typeof decoded.exp !== "number") {
                return null;
            }
            // The 0 in Date(0) is the key; it sets the date to the epoch
            const expirationDate = new Date(0);
            expirationDate.setUTCSeconds(decoded.exp);
            return expirationDate;
        });
    }
    tokenSecondsRemaining(userId_1) {
        return token_service_awaiter(this, arguments, void 0, function* (userId, offsetSeconds = 0) {
            const date = yield this.getTokenExpirationDate(userId);
            if (date == null) {
                return 0;
            }
            const msRemaining = date.valueOf() - (new Date().valueOf() + offsetSeconds * 1000);
            return Math.round(msRemaining / 1000);
        });
    }
    tokenNeedsRefresh(userId_1) {
        return token_service_awaiter(this, arguments, void 0, function* (userId, minutes = 5) {
            const sRemaining = yield this.tokenSecondsRemaining(userId);
            return sRemaining < 60 * minutes;
        });
    }
    getUserId() {
        return token_service_awaiter(this, void 0, void 0, function* () {
            let decoded;
            try {
                decoded = yield this.decodeAccessToken();
            }
            catch (error) {
                throw new Error("Failed to decode access token: " + error.message);
            }
            if (!decoded || typeof decoded.sub !== "string") {
                throw new Error("No user id found");
            }
            return decoded.sub;
        });
    }
    getUserIdFromAccessToken(accessToken) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            let decoded;
            try {
                decoded = yield this.decodeAccessToken(accessToken);
            }
            catch (error) {
                throw new Error("Failed to decode access token: " + error.message);
            }
            if (!decoded || typeof decoded.sub !== "string") {
                throw new Error("No user id found");
            }
            return decoded.sub;
        });
    }
    getEmail() {
        return token_service_awaiter(this, void 0, void 0, function* () {
            let decoded;
            try {
                decoded = yield this.decodeAccessToken();
            }
            catch (error) {
                throw new Error("Failed to decode access token: " + error.message);
            }
            if (!decoded || typeof decoded.email !== "string") {
                throw new Error("No email found");
            }
            return decoded.email;
        });
    }
    getEmailVerified() {
        return token_service_awaiter(this, void 0, void 0, function* () {
            let decoded;
            try {
                decoded = yield this.decodeAccessToken();
            }
            catch (error) {
                throw new Error("Failed to decode access token: " + error.message);
            }
            if (!decoded || typeof decoded.email_verified !== "boolean") {
                throw new Error("No email verification found");
            }
            return decoded.email_verified;
        });
    }
    getName() {
        return token_service_awaiter(this, void 0, void 0, function* () {
            let decoded;
            try {
                decoded = yield this.decodeAccessToken();
            }
            catch (error) {
                throw new Error("Failed to decode access token: " + error.message);
            }
            if (!decoded || typeof decoded.name !== "string") {
                return null;
            }
            return decoded.name;
        });
    }
    getIssuer() {
        return token_service_awaiter(this, void 0, void 0, function* () {
            let decoded;
            try {
                decoded = yield this.decodeAccessToken();
            }
            catch (error) {
                throw new Error("Failed to decode access token: " + error.message);
            }
            if (!decoded || typeof decoded.iss !== "string") {
                throw new Error("No issuer found");
            }
            return decoded.iss;
        });
    }
    getIsExternal(userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            let decoded;
            try {
                decoded = yield this.decodeAccessToken(userId);
            }
            catch (error) {
                throw new Error("Failed to decode access token: " + error.message);
            }
            return Array.isArray(decoded.amr) && decoded.amr.includes("external");
        });
    }
    getSecurityStamp(userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            userId !== null && userId !== void 0 ? userId : (userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.activeUserIdGlobalState.state$));
            if (!userId) {
                throw new Error("User id not found. Cannot get security stamp.");
            }
            const securityStamp = yield this.getStateValueByUserIdAndKeyDef(userId, SECURITY_STAMP_MEMORY);
            return securityStamp;
        });
    }
    setSecurityStamp(securityStamp, userId) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            userId !== null && userId !== void 0 ? userId : (userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.activeUserIdGlobalState.state$));
            if (!userId) {
                throw new Error("User id not found. Cannot set security stamp.");
            }
            yield this.singleUserStateProvider
                .get(userId, SECURITY_STAMP_MEMORY)
                .update((_) => securityStamp);
        });
    }
    getStateValueByUserIdAndKeyDef(userId, storageLocation) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            // read from single user state provider
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.singleUserStateProvider.get(userId, storageLocation).state$);
        });
    }
    /**
     * Determines where tokens should be stored based on vault timeout settings.
     *
     * | Vault Timeout Action | Vault Timeout   | Token Storage        |
     * |----------------------|-----------------|----------------------|
     * | Lock                 | Any             | Disk / Secure Storage|
     * | Log Out              | Never           | Disk / Secure Storage|
     * | Log Out              | Any other value | Memory only          |
     *
     * Memory-only tokens are cleared when the app closes.
     */
    determineStorageLocation(vaultTimeoutAction, vaultTimeout, useSecureStorage) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            if (vaultTimeoutAction == null) {
                throw new Error("TokenService - determineStorageLocation: We expect the vault timeout action to always exist at this point.");
            }
            if (vaultTimeout == null) {
                throw new Error("TokenService - determineStorageLocation: We expect the vault timeout to always exist at this point.");
            }
            if (vaultTimeoutAction === VaultTimeoutAction.LogOut &&
                vaultTimeout !== VaultTimeoutStringType.Never) {
                return TokenStorageLocation.Memory;
            }
            else {
                // Secure storage (e.g., OS credential manager) is preferred when available.
                // Desktop portable builds set platformSupportsSecureStorage=false to store tokens
                // on disk for portability across machines.
                if (useSecureStorage && this.platformSupportsSecureStorage) {
                    return TokenStorageLocation.SecureStorage;
                }
                return TokenStorageLocation.Disk;
            }
        });
    }
    saveStringToSecureStorage(userId, storageKey, value) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            yield this.secureStorageService.save(`${userId}${storageKey}`, value, this.getSecureStorageOptions(userId));
        });
    }
    getStringFromSecureStorage(userId, storageKey) {
        return token_service_awaiter(this, void 0, void 0, function* () {
            // If we have a user ID, read from secure storage.
            return yield this.secureStorageService.get(`${userId}${storageKey}`, this.getSecureStorageOptions(userId));
        });
    }
    getSecureStorageOptions(userId) {
        return {
            storageLocation: StorageLocationEnum.Disk,
            useSecureStorage: true,
            userId: userId,
        };
    }
}

;// ../../libs/common/src/auth/services/user-verification/user-verification-api.service.ts
var user_verification_api_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
class UserVerificationApiService {
    constructor(apiService) {
        this.apiService = apiService;
    }
    postAccountVerifyOTP(request) {
        return this.apiService.send("POST", "/accounts/verify-otp", request, true, false);
    }
    postAccountRequestOTP() {
        return user_verification_api_service_awaiter(this, void 0, void 0, function* () {
            return this.apiService.send("POST", "/accounts/request-otp", null, true, false);
        });
    }
    postAccountVerifyPassword(request) {
        return this.apiService.send("POST", "/accounts/verify-password", request, true, true);
    }
}

;// ../../libs/common/src/auth/enums/verification-type.ts
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var VerificationType;
(function (VerificationType) {
    VerificationType[VerificationType["MasterPassword"] = 0] = "MasterPassword";
    VerificationType[VerificationType["OTP"] = 1] = "OTP";
    VerificationType[VerificationType["PIN"] = 2] = "PIN";
    VerificationType[VerificationType["Biometrics"] = 3] = "Biometrics";
})(VerificationType || (VerificationType = {}));

;// ../../libs/common/src/auth/models/request/verify-otp.request.ts
class VerifyOTPRequest {
    constructor(OTP) {
        this.OTP = OTP;
    }
}

;// ../../libs/common/src/auth/types/verification.ts
function verificationHasSecret(verification) {
    return "secret" in verification;
}

;// ../../libs/common/src/auth/services/user-verification/user-verification.service.ts
var user_verification_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop.
// eslint-disable-next-line no-restricted-imports






/**
 * Used for general-purpose user verification throughout the app.
 * Use it to verify the input collected by UserVerificationComponent.
 */
class UserVerificationService {
    constructor(keyService, accountService, masterPasswordService, i18nService, userVerificationApiService, userDecryptionOptionsService, pinService, kdfConfigService, biometricsService, masterPasswordUnlockService) {
        this.keyService = keyService;
        this.accountService = accountService;
        this.masterPasswordService = masterPasswordService;
        this.i18nService = i18nService;
        this.userVerificationApiService = userVerificationApiService;
        this.userDecryptionOptionsService = userDecryptionOptionsService;
        this.pinService = pinService;
        this.kdfConfigService = kdfConfigService;
        this.biometricsService = biometricsService;
        this.masterPasswordUnlockService = masterPasswordUnlockService;
    }
    getAvailableVerificationOptions(verificationType) {
        return user_verification_service_awaiter(this, void 0, void 0, function* () {
            var _a;
            const userId = (_a = (yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$))) === null || _a === void 0 ? void 0 : _a.id;
            if (verificationType === "client") {
                const [userHasMasterPassword, isPinDecryptionAvailable, biometricsStatus] = yield Promise.all([
                    this.hasMasterPassword(userId),
                    this.pinService.isPinDecryptionAvailable(userId),
                    this.biometricsService.getBiometricsStatus(),
                ]);
                // note: we do not need to check this.platformUtilsService.supportsBiometric() because
                // we can just use the logic below which works for both desktop & the browser extension.
                return {
                    client: {
                        masterPassword: userHasMasterPassword,
                        pin: isPinDecryptionAvailable,
                        biometrics: biometricsStatus === BiometricsStatus.Available,
                    },
                    server: {
                        masterPassword: false,
                        otp: false,
                    },
                };
            }
            else {
                // server
                // Don't check if have MP hash locally, because we are going to send the secret to the server to be verified.
                const userHasMasterPassword = yield this.hasMasterPassword(userId);
                return {
                    client: {
                        masterPassword: false,
                        pin: false,
                        biometrics: false,
                    },
                    server: { masterPassword: userHasMasterPassword, otp: !userHasMasterPassword },
                };
            }
        });
    }
    buildRequest(verification, requestClass) {
        return user_verification_service_awaiter(this, void 0, void 0, function* () {
            this.validateSecretInput(verification);
            const request = requestClass != null ? new requestClass() : new SecretVerificationRequest();
            if (verification.type === VerificationType.OTP) {
                request.otp = verification.secret;
            }
            else {
                const userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
                const kdf = yield this.kdfConfigService.getKdfConfig(userId);
                const salt = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.masterPasswordService.saltForUser$(userId));
                const authenticationData = yield this.masterPasswordService.makeMasterPasswordAuthenticationData(verification.secret, kdf, salt);
                request.authenticateWith(authenticationData);
            }
            return request;
        });
    }
    verifyUser(verification) {
        return user_verification_service_awaiter(this, void 0, void 0, function* () {
            if (verification == null) {
                throw new Error("Verification is required.");
            }
            const [userId, email] = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.map)((a) => [a === null || a === void 0 ? void 0 : a.id, a === null || a === void 0 ? void 0 : a.email])));
            if (verificationHasSecret(verification)) {
                this.validateSecretInput(verification);
            }
            switch (verification.type) {
                case VerificationType.OTP:
                    return this.verifyUserByOTP(verification);
                case VerificationType.MasterPassword:
                    yield this.verifyUserByMasterPassword(verification, userId, email);
                    return true;
                case VerificationType.PIN:
                    return this.verifyUserByPIN(verification, userId);
                case VerificationType.Biometrics:
                    return this.verifyUserByBiometrics();
                default: {
                    // Compile-time check for exhaustive switch
                    const _exhaustiveCheck = verification;
                    return _exhaustiveCheck;
                }
            }
        });
    }
    verifyUserByOTP(verification) {
        return user_verification_service_awaiter(this, void 0, void 0, function* () {
            const request = new VerifyOTPRequest(verification.secret);
            try {
                yield this.userVerificationApiService.postAccountVerifyOTP(request);
                // FIXME: Remove when updating file. Eslint update
                // eslint-disable-next-line @typescript-eslint/no-unused-vars
            }
            catch (e) {
                throw new Error(this.i18nService.t("invalidVerificationCode"));
            }
            return true;
        });
    }
    verifyUserByMasterPassword(verification, userId, email) {
        return user_verification_service_awaiter(this, void 0, void 0, function* () {
            if (!verification.secret) {
                throw new Error("Master Password is required. Cannot verify user without a master password.");
            }
            if (!userId) {
                throw new Error("User ID is required. Cannot verify user by master password.");
            }
            if (!email) {
                throw new Error("Email is required. Cannot verify user by master password.");
            }
            const kdfConfig = yield this.kdfConfigService.getKdfConfig(userId);
            if (!kdfConfig) {
                throw new Error("KDF config is required. Cannot verify user by master password.");
            }
            let policyOptions;
            // Client-side verification
            if (yield this.hasMasterPassword(userId)) {
                const passwordValid = yield this.masterPasswordUnlockService.proofOfDecryption(verification.secret, userId);
                if (!passwordValid) {
                    throw new Error(this.i18nService.t("invalidMasterPassword"));
                }
                policyOptions = null;
            }
            else {
                // Server-side verification
                const request = new SecretVerificationRequest();
                const authenticationData = yield this.masterPasswordService.makeMasterPasswordAuthenticationData(verification.secret, kdfConfig, yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.masterPasswordService.saltForUser$(userId)));
                request.authenticateWith(authenticationData);
                try {
                    policyOptions = yield this.userVerificationApiService.postAccountVerifyPassword(request);
                    // FIXME: Remove when updating file. Eslint update
                    // eslint-disable-next-line @typescript-eslint/no-unused-vars
                }
                catch (e) {
                    throw new Error(this.i18nService.t("invalidMasterPassword"));
                }
            }
            return { policyOptions, email };
        });
    }
    verifyUserByPIN(verification, userId) {
        return user_verification_service_awaiter(this, void 0, void 0, function* () {
            if (!userId) {
                throw new Error("User ID is required. Cannot verify user by PIN.");
            }
            const userKey = yield this.pinService.decryptUserKeyWithPin(verification.secret, userId);
            return userKey != null;
        });
    }
    verifyUserByBiometrics() {
        return user_verification_service_awaiter(this, void 0, void 0, function* () {
            return this.biometricsService.authenticateWithBiometrics();
        });
    }
    requestOTP() {
        return user_verification_service_awaiter(this, void 0, void 0, function* () {
            yield this.userVerificationApiService.postAccountRequestOTP();
        });
    }
    hasMasterPassword(userId) {
        return user_verification_service_awaiter(this, void 0, void 0, function* () {
            var _a;
            const resolvedUserId = userId !== null && userId !== void 0 ? userId : (_a = (yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$))) === null || _a === void 0 ? void 0 : _a.id;
            if (!resolvedUserId) {
                return false;
            }
            // Ideally, this method would accept a UserId over string. To avoid scope creep in PM-26413, we are
            // doing the cast here. Future work should be done to make this type-safe, and should be considered
            // as part of PM-27009.
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.userDecryptionOptionsService.hasMasterPasswordById$(resolvedUserId));
        });
    }
    validateSecretInput(verification) {
        if ((verification === null || verification === void 0 ? void 0 : verification.secret) == null || verification.secret === "") {
            switch (verification.type) {
                case VerificationType.OTP:
                    throw new Error(this.i18nService.t("verificationCodeRequired"));
                case VerificationType.MasterPassword:
                    throw new Error(this.i18nService.t("masterPasswordRequired"));
                case VerificationType.PIN:
                    throw new Error(this.i18nService.t("pinRequired"));
            }
        }
    }
}

;// ../../libs/common/src/auth/two-factor/abstractions/two-factor.service.ts


/**
 * Registry of all supported two-factor authentication providers with their metadata.
 * Strings (name, description) are initialized as null and populated with localized
 * translations when {@link TwoFactorService.init} is called during application startup.
 *
 * @remarks
 * This constant is mutated during initialization. Components should not access it before
 * the service's init() method has been called.
 *
 * @example
 * ```typescript
 * // During app init
 * twoFactorService.init();
 *
 * // In components
 * const authenticator = TwoFactorProviders[TwoFactorProviderType.Authenticator];
 * console.log(authenticator.name); // "Authenticator App" (localized)
 * ```
 */
const TwoFactorProviders = {
    [TwoFactorProviderType.Authenticator]: {
        type: TwoFactorProviderType.Authenticator,
        name: null,
        description: null,
        priority: 1,
        sort: 2,
        premium: false,
    },
    [TwoFactorProviderType.Yubikey]: {
        type: TwoFactorProviderType.Yubikey,
        name: null,
        description: null,
        priority: 3,
        sort: 4,
        premium: true,
    },
    [TwoFactorProviderType.Duo]: {
        type: TwoFactorProviderType.Duo,
        name: "Duo",
        description: null,
        priority: 2,
        sort: 5,
        premium: true,
    },
    [TwoFactorProviderType.OrganizationDuo]: {
        type: TwoFactorProviderType.OrganizationDuo,
        name: "Duo (Organization)",
        description: null,
        priority: 10,
        sort: 6,
        premium: false,
    },
    [TwoFactorProviderType.Email]: {
        type: TwoFactorProviderType.Email,
        name: null,
        description: null,
        priority: 0,
        sort: 1,
        premium: false,
    },
    [TwoFactorProviderType.WebAuthn]: {
        type: TwoFactorProviderType.WebAuthn,
        name: null,
        description: null,
        priority: 4,
        sort: 3,
        premium: false,
    },
};
// Memory storage as only required during authentication process
const two_factor_service_PROVIDERS = KeyDefinition.record(TWO_FACTOR_MEMORY, "providers", {
    deserializer: (obj) => obj,
});
// Memory storage as only required during authentication process
const SELECTED_PROVIDER = new KeyDefinition(TWO_FACTOR_MEMORY, "selected", {
    deserializer: (obj) => obj,
});
class TwoFactorService {
}

;// ../../libs/common/src/auth/two-factor/abstractions/index.ts



;// ../../libs/common/src/auth/models/response/two-factor-authenticator.response.ts

class TwoFactorAuthenticatorResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.enabled = this.getResponseProperty("Enabled");
        this.key = this.getResponseProperty("Key");
        this.userVerificationToken = this.getResponseProperty("UserVerificationToken");
    }
}

;// ../../libs/common/src/auth/models/response/two-factor-duo.response.ts

class TwoFactorDuoResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.enabled = this.getResponseProperty("Enabled");
        this.host = this.getResponseProperty("Host");
        this.clientSecret = this.getResponseProperty("ClientSecret");
        this.clientId = this.getResponseProperty("ClientId");
    }
}

;// ../../libs/common/src/auth/models/response/two-factor-email.response.ts

class TwoFactorEmailResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.enabled = this.getResponseProperty("Enabled");
        this.email = this.getResponseProperty("Email");
    }
}

;// ../../libs/common/src/auth/models/response/two-factor-provider.response.ts

class TwoFactorProviderResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.enabled = this.getResponseProperty("Enabled");
        this.type = this.getResponseProperty("Type");
    }
}

;// ../../libs/common/src/auth/models/response/two-factor-recover.response.ts

class TwoFactorRecoverResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.code = this.getResponseProperty("Code");
    }
}

;// ../../libs/common/src/auth/models/response/two-factor-web-authn.response.ts


class TwoFactorWebAuthnResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.enabled = this.getResponseProperty("Enabled");
        const keys = this.getResponseProperty("Keys");
        this.keys = keys == null ? null : keys.map((k) => new KeyResponse(k));
    }
}
class KeyResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.name = this.getResponseProperty("Name");
        this.id = this.getResponseProperty("Id");
        this.migrated = this.getResponseProperty("Migrated");
    }
}
class ChallengeResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.attestation = this.getResponseProperty("attestation");
        this.authenticatorSelection = this.getResponseProperty("authenticatorSelection");
        this.challenge = utils_Utils.fromUrlB64ToArray(this.getResponseProperty("challenge"));
        this.excludeCredentials = this.getResponseProperty("excludeCredentials").map((c) => {
            c.id = utils_Utils.fromUrlB64ToArray(c.id).buffer;
            return c;
        });
        this.extensions = this.getResponseProperty("extensions");
        this.pubKeyCredParams = this.getResponseProperty("pubKeyCredParams");
        this.rp = this.getResponseProperty("rp");
        this.timeout = this.getResponseProperty("timeout");
        const user = this.getResponseProperty("user");
        user.id = utils_Utils.fromUrlB64ToArray(user.id);
        this.user = user;
    }
}

;// ../../libs/common/src/auth/models/response/two-factor-yubi-key.response.ts

class TwoFactorYubiKeyResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.enabled = this.getResponseProperty("Enabled");
        this.key1 = this.getResponseProperty("Key1");
        this.key2 = this.getResponseProperty("Key2");
        this.key3 = this.getResponseProperty("Key3");
        this.key4 = this.getResponseProperty("Key4");
        this.key5 = this.getResponseProperty("Key5");
        this.nfc = this.getResponseProperty("Nfc");
    }
}

;// ../../libs/common/src/auth/two-factor/services/default-two-factor-api.service.ts
var default_two_factor_api_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};









class DefaultTwoFactorApiService {
    constructor(apiService) {
        this.apiService = apiService;
    }
    // Providers
    getTwoFactorProviders() {
        return default_two_factor_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.send("GET", "/two-factor", null, true, true);
            return new ListResponse(response, TwoFactorProviderResponse);
        });
    }
    getTwoFactorOrganizationProviders(organizationId) {
        return default_two_factor_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.send("GET", `/organizations/${organizationId}/two-factor`, null, true, true);
            return new ListResponse(response, TwoFactorProviderResponse);
        });
    }
    // Authenticator (TOTP)
    getTwoFactorAuthenticator(request) {
        return default_two_factor_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.send("POST", "/two-factor/get-authenticator", request, true, true);
            return new TwoFactorAuthenticatorResponse(response);
        });
    }
    putTwoFactorAuthenticator(request) {
        return default_two_factor_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.send("PUT", "/two-factor/authenticator", request, true, true);
            return new TwoFactorAuthenticatorResponse(response);
        });
    }
    deleteTwoFactorAuthenticator(request) {
        return default_two_factor_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.send("DELETE", "/two-factor/authenticator", request, true, true);
            return new TwoFactorProviderResponse(response);
        });
    }
    // Email
    getTwoFactorEmail(request) {
        return default_two_factor_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.send("POST", "/two-factor/get-email", request, true, true);
            return new TwoFactorEmailResponse(response);
        });
    }
    postTwoFactorEmailSetup(request) {
        return default_two_factor_api_service_awaiter(this, void 0, void 0, function* () {
            return this.apiService.send("POST", "/two-factor/send-email", request, true, false);
        });
    }
    postTwoFactorEmail(request) {
        return default_two_factor_api_service_awaiter(this, void 0, void 0, function* () {
            return this.apiService.send("POST", "/two-factor/send-email-login", request, false, false);
        });
    }
    putTwoFactorEmail(request) {
        return default_two_factor_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.send("PUT", "/two-factor/email", request, true, true);
            return new TwoFactorEmailResponse(response);
        });
    }
    // Duo
    getTwoFactorDuo(request) {
        return default_two_factor_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.send("POST", "/two-factor/get-duo", request, true, true);
            return new TwoFactorDuoResponse(response);
        });
    }
    getTwoFactorOrganizationDuo(organizationId, request) {
        return default_two_factor_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.send("POST", `/organizations/${organizationId}/two-factor/get-duo`, request, true, true);
            return new TwoFactorDuoResponse(response);
        });
    }
    putTwoFactorDuo(request) {
        return default_two_factor_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.send("PUT", "/two-factor/duo", request, true, true);
            return new TwoFactorDuoResponse(response);
        });
    }
    putTwoFactorOrganizationDuo(organizationId, request) {
        return default_two_factor_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.send("PUT", `/organizations/${organizationId}/two-factor/duo`, request, true, true);
            return new TwoFactorDuoResponse(response);
        });
    }
    // YubiKey
    getTwoFactorYubiKey(request) {
        return default_two_factor_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.send("POST", "/two-factor/get-yubikey", request, true, true);
            return new TwoFactorYubiKeyResponse(response);
        });
    }
    putTwoFactorYubiKey(request) {
        return default_two_factor_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.send("PUT", "/two-factor/yubikey", request, true, true);
            return new TwoFactorYubiKeyResponse(response);
        });
    }
    // WebAuthn
    getTwoFactorWebAuthn(request) {
        return default_two_factor_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.send("POST", "/two-factor/get-webauthn", request, true, true);
            return new TwoFactorWebAuthnResponse(response);
        });
    }
    getTwoFactorWebAuthnChallenge(request) {
        return default_two_factor_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.send("POST", "/two-factor/get-webauthn-challenge", request, true, true);
            return new ChallengeResponse(response);
        });
    }
    putTwoFactorWebAuthn(request) {
        return default_two_factor_api_service_awaiter(this, void 0, void 0, function* () {
            const deviceResponse = request.deviceResponse.response;
            const body = Object.assign({}, request);
            body.deviceResponse = {
                id: request.deviceResponse.id,
                rawId: btoa(request.deviceResponse.id),
                type: request.deviceResponse.type,
                extensions: request.deviceResponse.getClientExtensionResults(),
                response: {
                    AttestationObject: utils_Utils.fromBufferToB64(deviceResponse.attestationObject),
                    clientDataJson: utils_Utils.fromBufferToB64(deviceResponse.clientDataJSON),
                },
            };
            const response = yield this.apiService.send("PUT", "/two-factor/webauthn", body, true, true);
            return new TwoFactorWebAuthnResponse(response);
        });
    }
    deleteTwoFactorWebAuthn(request) {
        return default_two_factor_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.send("DELETE", "/two-factor/webauthn", request, true, true);
            return new TwoFactorWebAuthnResponse(response);
        });
    }
    // Recovery Code
    getTwoFactorRecover(request) {
        return default_two_factor_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.send("POST", "/two-factor/get-recover", request, true, true);
            return new TwoFactorRecoverResponse(response);
        });
    }
    // Disable
    putTwoFactorDisable(request) {
        return default_two_factor_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.send("PUT", "/two-factor/disable", request, true, true);
            return new TwoFactorProviderResponse(response);
        });
    }
    putTwoFactorOrganizationDisable(organizationId, request) {
        return default_two_factor_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.apiService.send("PUT", `/organizations/${organizationId}/two-factor/disable`, request, true, true);
            return new TwoFactorProviderResponse(response);
        });
    }
}

;// ../../libs/common/src/auth/two-factor/services/default-two-factor.service.ts
var default_two_factor_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore




class DefaultTwoFactorService {
    constructor(i18nService, platformUtilsService, globalStateProvider, twoFactorApiService) {
        this.i18nService = i18nService;
        this.platformUtilsService = platformUtilsService;
        this.globalStateProvider = globalStateProvider;
        this.twoFactorApiService = twoFactorApiService;
        this.providersState = this.globalStateProvider.get(two_factor_service_PROVIDERS);
        this.selectedState = this.globalStateProvider.get(SELECTED_PROVIDER);
        this.providers$ = this.providersState.state$.pipe((0,external_rxjs_namespaceObject.map)((providers) => utils_Utils.recordToMap(providers)));
        this.selected$ = this.selectedState.state$;
    }
    init() {
        TwoFactorProviders[TwoFactorProviderType.Email].name = this.i18nService.t("emailTitle");
        TwoFactorProviders[TwoFactorProviderType.Email].description = this.i18nService.t("emailDescV2");
        TwoFactorProviders[TwoFactorProviderType.Authenticator].name =
            this.i18nService.t("authenticatorAppTitle");
        TwoFactorProviders[TwoFactorProviderType.Authenticator].description =
            this.i18nService.t("authenticatorAppDescV2");
        TwoFactorProviders[TwoFactorProviderType.Duo].description = this.i18nService.t("duoDescV2");
        TwoFactorProviders[TwoFactorProviderType.OrganizationDuo].name =
            "Duo (" + this.i18nService.t("organization") + ")";
        TwoFactorProviders[TwoFactorProviderType.OrganizationDuo].description =
            this.i18nService.t("duoOrganizationDesc");
        TwoFactorProviders[TwoFactorProviderType.WebAuthn].name = this.i18nService.t("webAuthnTitle");
        TwoFactorProviders[TwoFactorProviderType.WebAuthn].description =
            this.i18nService.t("webAuthnDesc");
        TwoFactorProviders[TwoFactorProviderType.Yubikey].name = this.i18nService.t("yubiKeyTitleV2");
        TwoFactorProviders[TwoFactorProviderType.Yubikey].description =
            this.i18nService.t("yubiKeyDesc");
    }
    getSupportedProviders(win) {
        return default_two_factor_service_awaiter(this, void 0, void 0, function* () {
            const data = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.providers$);
            const providers = [];
            if (data == null) {
                return providers;
            }
            if (data.has(TwoFactorProviderType.OrganizationDuo) &&
                this.platformUtilsService.supportsDuo()) {
                providers.push(TwoFactorProviders[TwoFactorProviderType.OrganizationDuo]);
            }
            if (data.has(TwoFactorProviderType.Authenticator)) {
                providers.push(TwoFactorProviders[TwoFactorProviderType.Authenticator]);
            }
            if (data.has(TwoFactorProviderType.Yubikey)) {
                providers.push(TwoFactorProviders[TwoFactorProviderType.Yubikey]);
            }
            if (data.has(TwoFactorProviderType.Duo) && this.platformUtilsService.supportsDuo()) {
                providers.push(TwoFactorProviders[TwoFactorProviderType.Duo]);
            }
            if (data.has(TwoFactorProviderType.WebAuthn) &&
                this.platformUtilsService.supportsWebAuthn(win)) {
                providers.push(TwoFactorProviders[TwoFactorProviderType.WebAuthn]);
            }
            if (data.has(TwoFactorProviderType.Email)) {
                providers.push(TwoFactorProviders[TwoFactorProviderType.Email]);
            }
            return providers;
        });
    }
    getDefaultProvider(webAuthnSupported) {
        return default_two_factor_service_awaiter(this, void 0, void 0, function* () {
            const data = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.providers$);
            const selected = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.selected$);
            if (data == null) {
                return null;
            }
            if (selected != null && data.has(selected)) {
                return selected;
            }
            let providerType = null;
            let providerPriority = -1;
            data.forEach((_value, type) => {
                const provider = TwoFactorProviders[type];
                if (provider != null && provider.priority > providerPriority) {
                    if (type === TwoFactorProviderType.WebAuthn && !webAuthnSupported) {
                        return;
                    }
                    providerType = type;
                    providerPriority = provider.priority;
                }
            });
            return providerType;
        });
    }
    setSelectedProvider(type) {
        return default_two_factor_service_awaiter(this, void 0, void 0, function* () {
            yield this.selectedState.update(() => type);
        });
    }
    clearSelectedProvider() {
        return default_two_factor_service_awaiter(this, void 0, void 0, function* () {
            yield this.selectedState.update(() => null);
        });
    }
    setProviders(response) {
        return default_two_factor_service_awaiter(this, void 0, void 0, function* () {
            yield this.providersState.update(() => response.twoFactorProviders2);
        });
    }
    clearProviders() {
        return default_two_factor_service_awaiter(this, void 0, void 0, function* () {
            yield this.providersState.update(() => null);
        });
    }
    getProviders() {
        return (0,external_rxjs_namespaceObject.firstValueFrom)(this.providers$);
    }
    getEnabledTwoFactorProviders() {
        return this.twoFactorApiService.getTwoFactorProviders();
    }
    getTwoFactorOrganizationProviders(organizationId) {
        return this.twoFactorApiService.getTwoFactorOrganizationProviders(organizationId);
    }
    getTwoFactorAuthenticator(request) {
        return this.twoFactorApiService.getTwoFactorAuthenticator(request);
    }
    getTwoFactorEmail(request) {
        return this.twoFactorApiService.getTwoFactorEmail(request);
    }
    getTwoFactorDuo(request) {
        return this.twoFactorApiService.getTwoFactorDuo(request);
    }
    getTwoFactorOrganizationDuo(organizationId, request) {
        return this.twoFactorApiService.getTwoFactorOrganizationDuo(organizationId, request);
    }
    getTwoFactorYubiKey(request) {
        return this.twoFactorApiService.getTwoFactorYubiKey(request);
    }
    getTwoFactorWebAuthn(request) {
        return this.twoFactorApiService.getTwoFactorWebAuthn(request);
    }
    getTwoFactorWebAuthnChallenge(request) {
        return this.twoFactorApiService.getTwoFactorWebAuthnChallenge(request);
    }
    getTwoFactorRecover(request) {
        return this.twoFactorApiService.getTwoFactorRecover(request);
    }
    putTwoFactorAuthenticator(request) {
        return this.twoFactorApiService.putTwoFactorAuthenticator(request);
    }
    deleteTwoFactorAuthenticator(request) {
        return this.twoFactorApiService.deleteTwoFactorAuthenticator(request);
    }
    putTwoFactorEmail(request) {
        return this.twoFactorApiService.putTwoFactorEmail(request);
    }
    putTwoFactorDuo(request) {
        return this.twoFactorApiService.putTwoFactorDuo(request);
    }
    putTwoFactorOrganizationDuo(organizationId, request) {
        return this.twoFactorApiService.putTwoFactorOrganizationDuo(organizationId, request);
    }
    putTwoFactorYubiKey(request) {
        return this.twoFactorApiService.putTwoFactorYubiKey(request);
    }
    putTwoFactorWebAuthn(request) {
        return this.twoFactorApiService.putTwoFactorWebAuthn(request);
    }
    deleteTwoFactorWebAuthn(request) {
        return this.twoFactorApiService.deleteTwoFactorWebAuthn(request);
    }
    putTwoFactorDisable(request) {
        return this.twoFactorApiService.putTwoFactorDisable(request);
    }
    putTwoFactorOrganizationDisable(organizationId, request) {
        return this.twoFactorApiService.putTwoFactorOrganizationDisable(organizationId, request);
    }
    postTwoFactorEmailSetup(request) {
        return this.twoFactorApiService.postTwoFactorEmailSetup(request);
    }
    postTwoFactorEmail(request) {
        return this.twoFactorApiService.postTwoFactorEmail(request);
    }
}

;// ../../libs/common/src/auth/two-factor/services/index.ts



;// ../../libs/common/src/auth/two-factor/index.ts



;// ../../libs/common/src/autofill/services/autofill-settings.service.ts
var autofill_settings_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore






const AUTOFILL_ON_PAGE_LOAD = new UserKeyDefinition(AUTOFILL_SETTINGS_DISK, "autofillOnPageLoad", {
    deserializer: (value) => value !== null && value !== void 0 ? value : false,
    clearOn: [],
});
const AUTOFILL_ON_PAGE_LOAD_DEFAULT = new UserKeyDefinition(AUTOFILL_SETTINGS_DISK, "autofillOnPageLoadDefault", {
    deserializer: (value) => value !== null && value !== void 0 ? value : false,
    clearOn: [],
});
const AUTOFILL_ON_PAGE_LOAD_CALLOUT_DISMISSED = new UserKeyDefinition(AUTOFILL_SETTINGS_DISK, "autofillOnPageLoadCalloutIsDismissed", {
    deserializer: (value) => value !== null && value !== void 0 ? value : false,
    clearOn: [],
});
const AUTOFILL_ON_PAGE_LOAD_POLICY_TOAST_HAS_DISPLAYED = new UserKeyDefinition(AUTOFILL_SETTINGS_DISK, "autofillOnPageLoadPolicyToastHasDisplayed", {
    deserializer: (value) => value !== null && value !== void 0 ? value : false,
    clearOn: [],
});
const AUTO_COPY_TOTP = new UserKeyDefinition(AUTOFILL_SETTINGS_DISK, "autoCopyTotp", {
    deserializer: (value) => value !== null && value !== void 0 ? value : true,
    clearOn: [],
});
const INLINE_MENU_VISIBILITY = new KeyDefinition(AUTOFILL_SETTINGS_DISK_LOCAL, "inlineMenuVisibility", {
    deserializer: (value) => value !== null && value !== void 0 ? value : constants_AutofillOverlayVisibility.Off,
});
const SHOW_INLINE_MENU_IDENTITIES = new UserKeyDefinition(AUTOFILL_SETTINGS_DISK, "showInlineMenuIdentities", {
    deserializer: (value) => value !== null && value !== void 0 ? value : true,
    clearOn: [],
});
const SHOW_INLINE_MENU_CARDS = new UserKeyDefinition(AUTOFILL_SETTINGS_DISK, "showInlineMenuCards", {
    deserializer: (value) => value !== null && value !== void 0 ? value : true,
    clearOn: [],
});
const ENABLE_CONTEXT_MENU = new KeyDefinition(AUTOFILL_SETTINGS_DISK, "enableContextMenu", {
    deserializer: (value) => value !== null && value !== void 0 ? value : true,
});
const CLEAR_CLIPBOARD_DELAY = new UserKeyDefinition(AUTOFILL_SETTINGS_DISK_LOCAL, "clearClipboardDelay", {
    deserializer: (value) => value !== null && value !== void 0 ? value : constants_ClearClipboardDelay.FiveMinutes,
    clearOn: [],
});
const HAD_PRE_MIGRATION_CLIPBOARD_VALUE = new UserKeyDefinition(AUTOFILL_SETTINGS_DISK_LOCAL, "hadPreMigrationClipboardValue", {
    deserializer: (value) => value !== null && value !== void 0 ? value : false,
    clearOn: [],
});
const CLIPBOARD_SETTING_UPDATED_NOTIFICATION_DISMISSED = new UserKeyDefinition(AUTOFILL_SETTINGS_DISK, "clipboardSettingUpdatedNotificationDismissed", {
    deserializer: (value) => value !== null && value !== void 0 ? value : false,
    clearOn: [],
});
class AutofillSettingsServiceAbstraction {
}
class AutofillSettingsService {
    constructor(stateProvider, policyService, accountService, restrictedItemTypesService) {
        this.stateProvider = stateProvider;
        this.policyService = policyService;
        this.accountService = accountService;
        this.restrictedItemTypesService = restrictedItemTypesService;
        this.autofillOnPageLoadState = this.stateProvider.getActive(AUTOFILL_ON_PAGE_LOAD);
        this.autofillOnPageLoad$ = this.autofillOnPageLoadState.state$.pipe((0,external_rxjs_namespaceObject.map)((x) => x !== null && x !== void 0 ? x : false));
        this.autofillOnPageLoadDefaultState = this.stateProvider.getActive(AUTOFILL_ON_PAGE_LOAD_DEFAULT);
        this.autofillOnPageLoadDefault$ = this.autofillOnPageLoadDefaultState.state$.pipe((0,external_rxjs_namespaceObject.map)((x) => x !== null && x !== void 0 ? x : true));
        this.autofillOnPageLoadCalloutIsDismissedState = this.stateProvider.getActive(AUTOFILL_ON_PAGE_LOAD_CALLOUT_DISMISSED);
        this.autofillOnPageLoadCalloutIsDismissed$ =
            this.autofillOnPageLoadCalloutIsDismissedState.state$.pipe((0,external_rxjs_namespaceObject.map)((x) => x !== null && x !== void 0 ? x : false));
        this.activateAutofillOnPageLoadFromPolicy$ = this.accountService.activeAccount$.pipe(account_service_getUserId, (0,external_rxjs_namespaceObject.switchMap)((userId) => this.policyService.policyAppliesToUser$(policy_type_enum_PolicyType.ActivateAutofill, userId)));
        this.autofillOnPageLoadPolicyToastHasDisplayedState = this.stateProvider.getActive(AUTOFILL_ON_PAGE_LOAD_POLICY_TOAST_HAS_DISPLAYED);
        this.autofillOnPageLoadPolicyToastHasDisplayed$ =
            this.autofillOnPageLoadPolicyToastHasDisplayedState.state$.pipe((0,external_rxjs_namespaceObject.map)((x) => x !== null && x !== void 0 ? x : false));
        this.autoCopyTotpState = this.stateProvider.getActive(AUTO_COPY_TOTP);
        this.autoCopyTotp$ = this.autoCopyTotpState.state$.pipe((0,external_rxjs_namespaceObject.map)((x) => x !== null && x !== void 0 ? x : true));
        this.inlineMenuVisibilityState = this.stateProvider.getGlobal(INLINE_MENU_VISIBILITY);
        this.inlineMenuVisibility$ = this.inlineMenuVisibilityState.state$.pipe((0,external_rxjs_namespaceObject.map)((x) => x !== null && x !== void 0 ? x : constants_AutofillOverlayVisibility.Off));
        this.showInlineMenuIdentitiesState = this.stateProvider.getActive(SHOW_INLINE_MENU_IDENTITIES);
        this.showInlineMenuIdentities$ = this.showInlineMenuIdentitiesState.state$.pipe((0,external_rxjs_namespaceObject.map)((x) => x !== null && x !== void 0 ? x : true));
        this.showInlineMenuCardsState = this.stateProvider.getActive(SHOW_INLINE_MENU_CARDS);
        this.showInlineMenuCards$ = (0,external_rxjs_namespaceObject.combineLatest)([
            this.showInlineMenuCardsState.state$.pipe((0,external_rxjs_namespaceObject.map)((x) => x !== null && x !== void 0 ? x : true)),
            this.restrictedItemTypesService.restricted$,
        ]).pipe((0,external_rxjs_namespaceObject.map)(([enabled, restrictions]) => 
        // If enabled, show cards inline menu unless card type is restricted
        enabled && !restrictions.some((r) => r.cipherType === CipherType.Card)));
        this.enableContextMenuState = this.stateProvider.getGlobal(ENABLE_CONTEXT_MENU);
        this.enableContextMenu$ = this.enableContextMenuState.state$.pipe((0,external_rxjs_namespaceObject.map)((x) => x !== null && x !== void 0 ? x : true));
        this.clearClipboardDelayState = this.stateProvider.getActive(CLEAR_CLIPBOARD_DELAY);
        this.clearClipboardDelay$ = this.clearClipboardDelayState.state$.pipe((0,external_rxjs_namespaceObject.map)((x) => x !== null && x !== void 0 ? x : constants_ClearClipboardDelay.FiveMinutes));
        this.hadPreMigrationClipboardValueState = this.stateProvider.getActive(HAD_PRE_MIGRATION_CLIPBOARD_VALUE);
        this.hadPreMigrationClipboardValue$ = this.hadPreMigrationClipboardValueState.state$.pipe((0,external_rxjs_namespaceObject.map)((x) => x !== null && x !== void 0 ? x : false));
        this.clipboardSettingUpdatedNotificationDismissedState = this.stateProvider.getActive(CLIPBOARD_SETTING_UPDATED_NOTIFICATION_DISMISSED);
        this.clipboardSettingUpdatedNotificationDismissed$ =
            this.clipboardSettingUpdatedNotificationDismissedState.state$.pipe((0,external_rxjs_namespaceObject.map)((x) => x !== null && x !== void 0 ? x : false));
        // Observable that determines if notification should be shown
        // Shows notification if:
        // 1. User went through migration with null/Never value (hadPreMigrationValue is true)
        // 2. Notification hasn't been dismissed
        this.showClipboardSettingUpdateNotification$ = (0,external_rxjs_namespaceObject.combineLatest)([
            this.hadPreMigrationClipboardValue$,
            this.clipboardSettingUpdatedNotificationDismissed$,
        ]).pipe((0,external_rxjs_namespaceObject.map)(([hadPreMigrationValue, dismissed]) => {
            return hadPreMigrationValue && !dismissed;
        }));
    }
    setAutofillOnPageLoad(newValue) {
        return autofill_settings_service_awaiter(this, void 0, void 0, function* () {
            yield this.autofillOnPageLoadState.update(() => newValue);
        });
    }
    setAutofillOnPageLoadDefault(newValue) {
        return autofill_settings_service_awaiter(this, void 0, void 0, function* () {
            yield this.autofillOnPageLoadDefaultState.update(() => newValue);
        });
    }
    setAutofillOnPageLoadCalloutIsDismissed(newValue) {
        return autofill_settings_service_awaiter(this, void 0, void 0, function* () {
            yield this.autofillOnPageLoadCalloutIsDismissedState.update(() => newValue);
        });
    }
    setAutofillOnPageLoadPolicyToastHasDisplayed(newValue) {
        return autofill_settings_service_awaiter(this, void 0, void 0, function* () {
            yield this.autofillOnPageLoadPolicyToastHasDisplayedState.update(() => newValue);
        });
    }
    setAutoCopyTotp(newValue) {
        return autofill_settings_service_awaiter(this, void 0, void 0, function* () {
            yield this.autoCopyTotpState.update(() => newValue);
        });
    }
    setInlineMenuVisibility(newValue) {
        return autofill_settings_service_awaiter(this, void 0, void 0, function* () {
            yield this.inlineMenuVisibilityState.update(() => newValue);
        });
    }
    setShowInlineMenuIdentities(newValue) {
        return autofill_settings_service_awaiter(this, void 0, void 0, function* () {
            yield this.showInlineMenuIdentitiesState.update(() => newValue);
        });
    }
    setShowInlineMenuCards(newValue) {
        return autofill_settings_service_awaiter(this, void 0, void 0, function* () {
            yield this.showInlineMenuCardsState.update(() => newValue);
        });
    }
    setEnableContextMenu(newValue) {
        return autofill_settings_service_awaiter(this, void 0, void 0, function* () {
            yield this.enableContextMenuState.update(() => newValue);
        });
    }
    setClearClipboardDelay(newValue) {
        return autofill_settings_service_awaiter(this, void 0, void 0, function* () {
            yield this.clearClipboardDelayState.update(() => newValue);
        });
    }
    setClipboardSettingUpdatedNotificationDismissed(newValue) {
        return autofill_settings_service_awaiter(this, void 0, void 0, function* () {
            yield this.clipboardSettingUpdatedNotificationDismissedState.update(() => newValue);
        });
    }
}

;// ../../libs/common/src/autofill/utils/punycode.ts
/**
 * Decodes a single punycode-encoded label (without the "xn--" prefix)
 * back to its unicode representation per RFC 3492.
 */
function decodePunycodeLabel(rawEncoded) {
    // Reject empty and overlong inputs. DNS labels are limited to 63 octets;
    // the "xn--" prefix consumes 4, leaving at most 59 for the encoded body.
    if (rawEncoded.length === 0 || rawEncoded.length > 59) {
        throw new Error("Invalid punycode: label length out of range");
    }
    // RFC 3492 Section 5: decoding is case-insensitive
    const encoded = rawEncoded.toLowerCase();
    const base = 36;
    const tMin = 1;
    const tMax = 26;
    const initialBias = 72;
    const initialN = 128;
    const output = [];
    let i = 0;
    let n = initialN;
    let bias = initialBias;
    // Split at the last delimiter; everything before is literal ASCII
    const lastDelim = encoded.lastIndexOf("-");
    if (lastDelim >= 0) {
        for (let j = 0; j < lastDelim; j++) {
            output.push(encoded.charCodeAt(j));
        }
    }
    let pos = lastDelim >= 0 ? lastDelim + 1 : 0;
    while (pos < encoded.length) {
        const oldi = i;
        let w = 1;
        for (let k = base;; k += base) {
            if (pos >= encoded.length) {
                throw new Error("Invalid punycode");
            }
            const code = encoded.charCodeAt(pos++);
            let digit;
            if (code >= 0x61 && code <= 0x7a) {
                digit = code - 0x61; // a-z
            }
            else if (code >= 0x30 && code <= 0x39) {
                digit = code - 0x30 + 26; // 0-9
            }
            else {
                throw new Error("Invalid punycode character");
            }
            // Check overflow BEFORE mutation to avoid IEEE 754 precision loss
            if (digit > Math.floor((Number.MAX_SAFE_INTEGER - i) / w)) {
                throw new Error("Invalid punycode: overflow");
            }
            i += digit * w;
            const t = k <= bias ? tMin : k >= bias + tMax ? tMax : k - bias;
            if (digit < t) {
                break;
            }
            const baseMinusT = base - t;
            if (w > Math.floor(Number.MAX_SAFE_INTEGER / baseMinusT)) {
                throw new Error("Invalid punycode: overflow");
            }
            w *= baseMinusT;
        }
        const out = output.length + 1;
        bias = adapt(i - oldi, out, oldi === 0);
        n += Math.floor(i / out);
        if (n > 0x10ffff) {
            throw new Error("Invalid punycode: code point out of range");
        }
        i %= out;
        output.splice(i, 0, n);
        i++;
    }
    return String.fromCodePoint(...output);
}
/**
 * Adapts the bias value for punycode decoding per RFC 3492 Section 6.1.
 * The bias controls the threshold boundaries that determine how many
 * digits are needed to represent each delta, dynamically tuning the
 * encoding efficiency based on previously seen code points.
 */
function adapt(rawDelta, numPoints, firstTime) {
    const base = 36;
    const tMin = 1;
    const tMax = 26;
    const skew = 38;
    const damp = 700;
    let delta = firstTime ? Math.floor(rawDelta / damp) : Math.floor(rawDelta / 2);
    delta += Math.floor(delta / numPoints);
    let k = 0;
    while (delta > ((base - tMin) * tMax) >> 1) {
        delta = Math.floor(delta / (base - tMin));
        k += base;
    }
    return k + Math.floor(((base - tMin + 1) * delta) / (delta + skew));
}
/**
 * Converts a punycode-encoded hostname to its unicode representation.
 * Labels prefixed with "xn--" are decoded; others are passed through as-is.
 *
 * @example
 * punycodeToUnicode("xn--mnchen-3ya.de")  // "münchen.de"
 * punycodeToUnicode("example.com")        // "example.com"
 * punycodeToUnicode("example.com:8443")   // "example.com:8443"
 */
function punycodeToUnicode(host) {
    // IPv6 addresses (e.g. "[::1]:8443") cannot contain punycode labels;
    // return as-is to avoid misinterpreting colons as port separators.
    if (host.startsWith("[")) {
        return host;
    }
    // Separate port if present (e.g. "xn--mnchen-3ya.de:8443")
    const colonIndex = host.lastIndexOf(":");
    let hostname = host;
    let port = "";
    if (colonIndex >= 0) {
        const possiblePort = host.slice(colonIndex + 1);
        if (/^\d+$/.test(possiblePort)) {
            hostname = host.slice(0, colonIndex);
            port = ":" + possiblePort;
        }
    }
    const labels = hostname.split(".").map((label) => {
        if (label.toLowerCase().startsWith("xn--")) {
            try {
                return decodePunycodeLabel(label.slice(4));
            }
            catch (_a) {
                return label;
            }
        }
        return label;
    });
    return labels.join(".") + port;
}

;// ../../libs/common/src/autofill/services/domain-settings.service.ts
var domain_settings_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore










const SHOW_FAVICONS = new KeyDefinition(DOMAIN_SETTINGS_DISK, "showFavicons", {
    deserializer: (value) => value !== null && value !== void 0 ? value : true,
});
// Domain exclusion list for notifications
const NEVER_DOMAINS = new KeyDefinition(DOMAIN_SETTINGS_DISK, "neverDomains", {
    deserializer: (value) => value !== null && value !== void 0 ? value : null,
});
// Domain exclusion list for content script injections
const BLOCKED_INTERACTIONS_URIS = new KeyDefinition(DOMAIN_SETTINGS_DISK, "blockedInteractionsUris", {
    deserializer: (value) => value !== null && value !== void 0 ? value : {},
});
const EQUIVALENT_DOMAINS = new UserKeyDefinition(DOMAIN_SETTINGS_DISK, "equivalentDomains", {
    deserializer: (value) => value !== null && value !== void 0 ? value : null,
    clearOn: ["logout"],
});
const DEFAULT_URI_MATCH_STRATEGY = new UserKeyDefinition(DOMAIN_SETTINGS_DISK, "defaultUriMatchStrategy", {
    deserializer: (value) => value !== null && value !== void 0 ? value : domain_service_UriMatchStrategy.Domain,
    clearOn: [],
});
const SERVER_TARGETING_RULES = KeyDefinition.record(DOMAIN_SETTINGS_DISK, "fillAssistTargetingRulesByServer", {
    deserializer: (value) => value !== null && value !== void 0 ? value : null,
});
const ENABLE_FILL_ASSIST = new KeyDefinition(DOMAIN_SETTINGS_DISK, "enableFillAssist", {
    deserializer: (value) => value !== null && value !== void 0 ? value : false,
});
/**
 * The Domain Settings service; provides client settings state for "active client view" URI concerns
 */
class DomainSettingsService {
}
class DefaultDomainSettingsService {
    constructor(stateProvider, policyService, accountService, configService, environmentService, authService) {
        this.stateProvider = stateProvider;
        this.policyService = policyService;
        this.accountService = accountService;
        this.configService = configService;
        this.environmentService = environmentService;
        this.authService = authService;
        this.showFaviconsState = this.stateProvider.getGlobal(SHOW_FAVICONS);
        this.showFavicons$ = this.showFaviconsState.state$.pipe((0,external_rxjs_namespaceObject.map)((x) => x !== null && x !== void 0 ? x : true));
        this.neverDomainsState = this.stateProvider.getGlobal(NEVER_DOMAINS);
        this.neverDomains$ = this.neverDomainsState.state$.pipe((0,external_rxjs_namespaceObject.map)((x) => x !== null && x !== void 0 ? x : null));
        // Needs to be global to prevent pre-login injections
        this.blockedInteractionsUrisState = this.stateProvider.getGlobal(BLOCKED_INTERACTIONS_URIS);
        this.blockedInteractionsUris$ = this.blockedInteractionsUrisState.state$.pipe((0,external_rxjs_namespaceObject.map)((x) => x !== null && x !== void 0 ? x : {}));
        this.equivalentDomainsState = this.stateProvider.getActive(EQUIVALENT_DOMAINS);
        this.equivalentDomains$ = this.equivalentDomainsState.state$.pipe((0,external_rxjs_namespaceObject.map)((x) => x !== null && x !== void 0 ? x : null));
        this.defaultUriMatchStrategyState = this.stateProvider.getActive(DEFAULT_URI_MATCH_STRATEGY);
        this.defaultUriMatchStrategy$ = this.defaultUriMatchStrategyState.state$.pipe((0,external_rxjs_namespaceObject.map)((x) => x !== null && x !== void 0 ? x : domain_service_UriMatchStrategy.Domain));
        this.enableFillAssistState = this.stateProvider.getGlobal(ENABLE_FILL_ASSIST);
        this.enableFillAssist$ = this.enableFillAssistState.state$.pipe((0,external_rxjs_namespaceObject.map)((x) => x !== null && x !== void 0 ? x : false));
        this.targetingRules$ = this.environmentService.environment$.pipe((0,external_rxjs_namespaceObject.switchMap)((env) => this.stateProvider
            .getGlobal(SERVER_TARGETING_RULES)
            .state$.pipe((0,external_rxjs_namespaceObject.map)((records) => { var _a; return (_a = records === null || records === void 0 ? void 0 : records[env.getApiUrl()]) !== null && _a !== void 0 ? _a : null; }))), (0,external_rxjs_namespaceObject.shareReplay)({ bufferSize: 1, refCount: true }));
        this.defaultUriMatchStrategyPolicy$ = this.accountService.activeAccount$.pipe(account_service_getUserId, (0,external_rxjs_namespaceObject.switchMap)((userId) => this.policyService.policiesByType$(policy_type_enum_PolicyType.UriMatchDefaults, userId)), getFirstPolicy, (0,external_rxjs_namespaceObject.map)((policy) => {
            var _a;
            if (!(policy === null || policy === void 0 ? void 0 : policy.enabled) || (policy === null || policy === void 0 ? void 0 : policy.data) == null) {
                return null;
            }
            const data = (_a = policy.data) === null || _a === void 0 ? void 0 : _a.uriMatchDetection;
            // Validate that data is a valid UriMatchStrategy value
            return Object.values(domain_service_UriMatchStrategy).includes(data) ? data : null;
        }), (0,external_rxjs_namespaceObject.shareReplay)({ bufferSize: 1, refCount: true }));
        this.resolvedDefaultUriMatchStrategy$ = (0,external_rxjs_namespaceObject.combineLatest)([
            this.defaultUriMatchStrategy$,
            this.defaultUriMatchStrategyPolicy$,
        ]).pipe((0,external_rxjs_namespaceObject.map)(([userSettingValue, policySettingValue]) => policySettingValue || userSettingValue), (0,external_rxjs_namespaceObject.shareReplay)({ bufferSize: 1, refCount: true }));
    }
    setShowFavicons(newValue) {
        return domain_settings_service_awaiter(this, void 0, void 0, function* () {
            yield this.showFaviconsState.update(() => newValue);
        });
    }
    setNeverDomains(newValue) {
        return domain_settings_service_awaiter(this, void 0, void 0, function* () {
            yield this.neverDomainsState.update(() => newValue);
        });
    }
    setBlockedInteractionsUris(newValue) {
        return domain_settings_service_awaiter(this, void 0, void 0, function* () {
            yield this.blockedInteractionsUrisState.update(() => newValue);
        });
    }
    setEquivalentDomains(newValue, userId) {
        return domain_settings_service_awaiter(this, void 0, void 0, function* () {
            yield this.stateProvider.getUser(userId, EQUIVALENT_DOMAINS).update(() => newValue);
        });
    }
    setDefaultUriMatchStrategy(newValue) {
        return domain_settings_service_awaiter(this, void 0, void 0, function* () {
            yield this.defaultUriMatchStrategyState.update(() => newValue);
        });
    }
    getUrlEquivalentDomains(url) {
        const domains$ = this.equivalentDomains$.pipe((0,external_rxjs_namespaceObject.map)((equivalentDomains) => {
            const domain = utils_Utils.getDomain(url);
            if (domain == null || equivalentDomains == null) {
                return new Set();
            }
            const equivalents = equivalentDomains.filter((ed) => ed.includes(domain)).flat();
            return new Set(equivalents);
        }));
        return domains$;
    }
    setEnableFillAssist(newValue) {
        return domain_settings_service_awaiter(this, void 0, void 0, function* () {
            yield this.enableFillAssistState.update(() => newValue, {
                shouldUpdate: (current) => current !== newValue,
            });
        });
    }
    setTargetingRules(rules) {
        return domain_settings_service_awaiter(this, void 0, void 0, function* () {
            const env = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.environmentService.environment$);
            const apiUrl = env.getApiUrl();
            yield this.stateProvider
                .getGlobal(SERVER_TARGETING_RULES)
                .update((existing) => (Object.assign(Object.assign({}, existing), { [apiUrl]: rules })), {
                shouldUpdate: (existing) => (existing === null || existing === void 0 ? void 0 : existing[apiUrl]) !== rules,
            });
        });
    }
    getTargetingRulesForUrl(url) {
        return domain_settings_service_awaiter(this, void 0, void 0, function* () {
            var _a, _b, _c;
            const fillAssistFeatureEnabled = yield this.configService.getFeatureFlag(feature_flag_enum_FeatureFlag.FillAssistTargetingRules);
            if (!fillAssistFeatureEnabled) {
                return null;
            }
            const enableFillAssist = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.enableFillAssist$);
            if (!enableFillAssist) {
                return null;
            }
            // Fill Assist requires an unlocked vault
            const activeAccount = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$);
            if (!activeAccount) {
                return null;
            }
            const authStatus = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.authService.authStatusFor$(activeAccount.id));
            if (authStatus !== authentication_status_AuthenticationStatus.Unlocked) {
                return null;
            }
            const rules = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.targetingRules$);
            if (!rules || Object.keys(rules).length === 0) {
                return null;
            }
            let parsed;
            try {
                parsed = new URL(url);
            }
            catch (_d) {
                return null;
            }
            let hostRules = rules[parsed.host];
            // www subdomain equivalence: if no entry for www.example.com, try example.com
            if (hostRules === undefined && parsed.host.startsWith("www.")) {
                hostRules = rules[parsed.host.slice(4)];
            }
            // If the direct punycode lookup missed, try the unicode form of the host.
            // This handles rule providers that use unicode host keys (e.g. "münchen.de"
            // instead of "xn--mnchen-3ya.de").
            if (hostRules === undefined && parsed.host.includes("xn--")) {
                const unicodeHost = punycodeToUnicode(parsed.host);
                hostRules = rules[unicodeHost];
                // www subdomain equivalence on the unicode form
                if (hostRules === undefined && unicodeHost.startsWith("www.")) {
                    hostRules = rules[unicodeHost.slice(4)];
                }
            }
            // No rules for this host; fall through to heuristics
            if (hostRules === undefined) {
                return null;
            }
            // Hostname blocklisted (null or empty): suppress autofill on all paths
            if (hostRules === null || (!((_a = hostRules.forms) === null || _a === void 0 ? void 0 : _a.length) && !hostRules.pathnames)) {
                return [];
            }
            // Check for pathname-specific rules
            // Fall back to root path `/` to enable checking cases where
            // a rule signals a form that is ONLY on the domain's root page
            const pathname = (parsed.pathname.replace(/\/+$/, "") || "/");
            if (hostRules.pathnames != null && pathname in hostRules.pathnames) {
                const pathnameEntry = hostRules.pathnames[pathname];
                // Pathname blocklisted (null/undefined/empty): suppress autofill on this path
                if (!((_b = pathnameEntry === null || pathnameEntry === void 0 ? void 0 : pathnameEntry.forms) === null || _b === void 0 ? void 0 : _b.length)) {
                    return [];
                }
                return pathnameEntry.forms;
            }
            // No pathname-specific rule; fall back to hostname-level forms
            return ((_c = hostRules.forms) === null || _c === void 0 ? void 0 : _c.length) ? hostRules.forms : null;
        });
    }
}

;// ../../libs/common/src/billing/services/account/billing-account-profile-state.service.ts
var billing_account_profile_state_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};


const billing_account_profile_state_service_BILLING_ACCOUNT_PROFILE_KEY_DEFINITION = new UserKeyDefinition(BILLING_DISK, "accountProfile", {
    deserializer: (billingAccountProfile) => billingAccountProfile,
    clearOn: ["logout"],
});
class DefaultBillingAccountProfileStateService {
    constructor(stateProvider) {
        this.stateProvider = stateProvider;
    }
    hasPremiumFromAnyOrganization$(userId) {
        return this.stateProvider
            .getUser(userId, billing_account_profile_state_service_BILLING_ACCOUNT_PROFILE_KEY_DEFINITION)
            .state$.pipe((0,external_rxjs_namespaceObject.map)((profile) => !!(profile === null || profile === void 0 ? void 0 : profile.hasPremiumFromAnyOrganization)));
    }
    hasPremiumPersonally$(userId) {
        return this.stateProvider
            .getUser(userId, billing_account_profile_state_service_BILLING_ACCOUNT_PROFILE_KEY_DEFINITION)
            .state$.pipe((0,external_rxjs_namespaceObject.map)((profile) => !!(profile === null || profile === void 0 ? void 0 : profile.hasPremiumPersonally)));
    }
    hasPremiumFromAnySource$(userId) {
        return this.stateProvider
            .getUser(userId, billing_account_profile_state_service_BILLING_ACCOUNT_PROFILE_KEY_DEFINITION)
            .state$.pipe((0,external_rxjs_namespaceObject.map)((profile) => (profile === null || profile === void 0 ? void 0 : profile.hasPremiumFromAnyOrganization) === true ||
            (profile === null || profile === void 0 ? void 0 : profile.hasPremiumPersonally) === true));
    }
    setHasPremium(hasPremiumPersonally, hasPremiumFromAnyOrganization, userId) {
        return billing_account_profile_state_service_awaiter(this, void 0, void 0, function* () {
            yield this.stateProvider.getUser(userId, billing_account_profile_state_service_BILLING_ACCOUNT_PROFILE_KEY_DEFINITION).update((_) => {
                return {
                    hasPremiumPersonally: hasPremiumPersonally,
                    hasPremiumFromAnyOrganization: hasPremiumFromAnyOrganization,
                };
            }, {
                shouldUpdate: (state) => state == null ||
                    state.hasPremiumFromAnyOrganization !== hasPremiumFromAnyOrganization ||
                    state.hasPremiumPersonally !== hasPremiumPersonally,
            });
        });
    }
}

;// ../../libs/common/src/dirt/event-logs/services/event-collection.service.ts
var event_collection_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore







class EventCollectionService {
    constructor(cipherService, stateProvider, organizationService, eventUploadService, authService, accountService) {
        this.cipherService = cipherService;
        this.stateProvider = stateProvider;
        this.organizationService = organizationService;
        this.eventUploadService = eventUploadService;
        this.authService = authService;
        this.accountService = accountService;
        this.getOrgIds = (orgs) => {
            var _a, _b;
            return (_b = (_a = orgs === null || orgs === void 0 ? void 0 : orgs.filter((o) => o.useEvents)) === null || _a === void 0 ? void 0 : _a.map((x) => x.id)) !== null && _b !== void 0 ? _b : [];
        };
    }
    /** Adds an event to the active user's event collection
     *  @param eventType the event type to be added
     *  @param ciphers The collection of ciphers to log events for
     *  @param uploadImmediately in some cases the recorded events should be uploaded right after being added
     */
    collectMany(eventType_1, ciphers_1) {
        return event_collection_service_awaiter(this, arguments, void 0, function* (eventType, ciphers, uploadImmediately = false) {
            const userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(account_service_getUserId(this.accountService.activeAccount$));
            const eventStore = this.stateProvider.getUser(userId, key_definitions_EVENT_COLLECTION);
            if (!(yield this.shouldUpdate(userId, null, eventType, ciphers))) {
                return;
            }
            const events$ = this.organizationService.organizations$(userId).pipe((0,external_rxjs_namespaceObject.map)((orgs) => this.getOrgIds(orgs)), (0,external_rxjs_namespaceObject.map)((orgs) => ciphers
                .filter((c) => orgs.includes(c.organizationId))
                .map((c) => ({
                type: eventType,
                cipherId: c.id,
                date: new Date().toISOString(),
                organizationId: c.organizationId,
            }))));
            yield eventStore.update((currentEvents, newEvents) => [...(currentEvents !== null && currentEvents !== void 0 ? currentEvents : []), ...newEvents], {
                combineLatestWith: events$,
            });
            if (uploadImmediately) {
                yield this.eventUploadService.uploadEvents();
            }
        });
    }
    /** Adds an event to the active user's event collection
     *  @param eventType the event type to be added
     *  @param cipherId if provided the id of the cipher involved in the event
     *  @param uploadImmediately in some cases the recorded events should be uploaded right after being added
     *  @param organizationId the organizationId involved in the event. If the cipherId is not provided an organizationId is required
     */
    collect(eventType_1) {
        return event_collection_service_awaiter(this, arguments, void 0, function* (eventType, cipherId = null, uploadImmediately = false, organizationId = null) {
            const userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(account_service_getUserId(this.accountService.activeAccount$));
            const eventStore = this.stateProvider.getUser(userId, key_definitions_EVENT_COLLECTION);
            if (!(yield this.shouldUpdate(userId, organizationId, eventType, undefined, cipherId))) {
                return;
            }
            const event = new EventData();
            event.type = eventType;
            event.cipherId = cipherId;
            event.date = new Date().toISOString();
            event.organizationId = organizationId;
            yield eventStore.update((events) => {
                events = events !== null && events !== void 0 ? events : [];
                events.push(event);
                return events;
            });
            if (uploadImmediately) {
                yield this.eventUploadService.uploadEvents();
            }
        });
    }
    /** Verifies if the event collection should be updated for the provided information
     *  @param userId the active user's id
     *  @param cipherId the cipher for the event
     *  @param organizationId the organization for the event
     */
    shouldUpdate(userId_1) {
        return event_collection_service_awaiter(this, arguments, void 0, function* (userId, organizationId = null, eventType = null, ciphers = [], cipherId) {
            const cipher$ = (0,external_rxjs_namespaceObject.from)(this.cipherService.get(cipherId, userId));
            const orgIds$ = this.organizationService
                .organizations$(userId)
                .pipe((0,external_rxjs_namespaceObject.map)((orgs) => this.getOrgIds(orgs)));
            const [authStatus, orgIds, cipher] = yield (0,external_rxjs_namespaceObject.firstValueFrom)((0,external_rxjs_namespaceObject.zip)(this.authService.activeAccountStatus$, orgIds$, cipher$));
            // The user must be authorized
            if (authStatus != authentication_status_AuthenticationStatus.Unlocked) {
                return false;
            }
            // User must have organizations assigned to them
            if (orgIds == null || orgIds.length == 0) {
                return false;
            }
            // Individual vault export doesn't need cipher id or organization id.
            if (eventType == EventType.User_ClientExportedVault) {
                return true;
            }
            // If the cipherId was provided and a cipher exists, add it to the collection
            if (cipher != null) {
                ciphers.push(new CipherView(cipher));
            }
            // If no ciphers there must be an organization id provided
            if ((ciphers == null || ciphers.length == 0) && organizationId == null) {
                return false;
            }
            // If the input list of ciphers is provided. Check the ciphers to see if any
            // are in the user's org list
            if (ciphers != null && ciphers.length > 0) {
                const filtered = ciphers.filter((c) => orgIds.includes(c.organizationId));
                return filtered.length > 0;
            }
            // If the organization id is provided it must be in the user's org list
            if (organizationId != null && !orgIds.includes(organizationId)) {
                return false;
            }
            return true;
        });
    }
}

;// ../../libs/common/src/platform/scheduling/scheduled-task-name.enum.ts


;// ../../libs/common/src/dirt/event-logs/models/request/event.request.ts
class EventRequest {
}

;// ../../libs/common/src/dirt/event-logs/services/event-upload.service.ts
var event_upload_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore





class EventUploadService {
    constructor(apiService, stateProvider, logService, authService, taskSchedulerService) {
        this.apiService = apiService;
        this.stateProvider = stateProvider;
        this.logService = logService;
        this.authService = authService;
        this.taskSchedulerService = taskSchedulerService;
        this.inited = false;
    }
    init(checkOnInterval) {
        if (this.inited) {
            return;
        }
        this.inited = true;
        this.taskSchedulerService.registerTaskHandler(ScheduledTaskNames.eventUploadsInterval, () => this.uploadEvents());
        if (checkOnInterval) {
            void this.uploadEvents();
            this.taskSchedulerService.setInterval(ScheduledTaskNames.eventUploadsInterval, 60 * 1000);
        }
    }
    /** Upload the event collection from state.
     *  @param userId upload events for provided user. If not active user will be used.
     */
    uploadEvents(userId) {
        return event_upload_service_awaiter(this, void 0, void 0, function* () {
            if (!userId) {
                userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.stateProvider.activeUserId$);
            }
            if (!userId) {
                return;
            }
            const isUnlocked = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.authService
                .authStatusFor$(userId)
                .pipe((0,external_rxjs_namespaceObject.map)((status) => status === authentication_status_AuthenticationStatus.Unlocked)));
            if (!isUnlocked) {
                return;
            }
            const eventCollection = yield this.takeEvents(userId);
            if (eventCollection == null || eventCollection.length === 0) {
                return;
            }
            const request = eventCollection.map((e) => {
                const req = new EventRequest();
                req.type = e.type;
                req.cipherId = e.cipherId;
                req.date = e.date;
                req.organizationId = e.organizationId;
                return req;
            });
            try {
                yield this.apiService.postEventsCollect(request, userId);
            }
            catch (e) {
                this.logService.error(e);
                // Add the events back to state if there was an error and they were not uploaded.
                yield this.stateProvider.setUserState(key_definitions_EVENT_COLLECTION, eventCollection, userId);
            }
        });
    }
    /** Return user's events and then clear them from state
     *  @param userId the user to grab and clear events for
     */
    takeEvents(userId) {
        return event_upload_service_awaiter(this, void 0, void 0, function* () {
            let taken = null;
            yield this.stateProvider.getUser(userId, key_definitions_EVENT_COLLECTION).update((current) => {
                taken = current !== null && current !== void 0 ? current : [];
                return [];
            });
            return taken;
        });
    }
}

;// ../../libs/common/src/dirt/models/response/breach-account.response.ts

class BreachAccountResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.addedDate = this.getResponseProperty("AddedDate");
        this.breachDate = this.getResponseProperty("BreachDate");
        this.dataClasses = this.getResponseProperty("DataClasses");
        this.description = this.getResponseProperty("Description");
        this.domain = this.getResponseProperty("Domain");
        this.isActive = this.getResponseProperty("IsActive");
        this.isVerified = this.getResponseProperty("IsVerified");
        this.logoPath = this.getResponseProperty("LogoPath");
        this.modifiedDate = this.getResponseProperty("ModifiedDate");
        this.name = this.getResponseProperty("Name");
        this.pwnCount = this.getResponseProperty("PwnCount");
        this.title = this.getResponseProperty("Title");
    }
}

;// ../../libs/common/src/dirt/models/response/index.ts


;// ../../libs/common/src/dirt/models/index.ts


;// ../../libs/common/src/dirt/services/hibp-api.service.ts
var hibp_api_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

class HibpApiService {
    constructor(apiService) {
        this.apiService = apiService;
    }
    getHibpBreach(username) {
        return hibp_api_service_awaiter(this, void 0, void 0, function* () {
            const encodedUsername = encodeURIComponent(username);
            const r = yield this.apiService.send("GET", "/hibp/breach?username=" + encodedUsername, null, true, true);
            return r.map((a) => new BreachAccountResponse(a));
        });
    }
}

;// ../../libs/common/src/key-management/account-cryptography/default-account-cryptographic-state.service.ts
var default_account_cryptographic_state_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const ACCOUNT_CRYPTOGRAPHIC_STATE = new UserKeyDefinition(CRYPTO_DISK, "accountCryptographicState", {
    deserializer: (obj) => obj,
    clearOn: ["logout"],
});
class DefaultAccountCryptographicStateService {
    constructor(stateProvider) {
        this.stateProvider = stateProvider;
    }
    accountCryptographicState$(userId) {
        return this.stateProvider.getUserState$(ACCOUNT_CRYPTOGRAPHIC_STATE, userId);
    }
    setAccountCryptographicState(accountCryptographicState, userId) {
        return default_account_cryptographic_state_service_awaiter(this, void 0, void 0, function* () {
            yield this.stateProvider.setUserState(ACCOUNT_CRYPTOGRAPHIC_STATE, accountCryptographicState, userId);
        });
    }
    clearAccountCryptographicState(userId) {
        return default_account_cryptographic_state_service_awaiter(this, void 0, void 0, function* () {
            yield this.stateProvider.setUserState(ACCOUNT_CRYPTOGRAPHIC_STATE, null, userId);
        });
    }
}

;// ../../libs/common/src/key-management/crypto/key-generation/default-key-generation.service.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
var default_key_generation_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};





class DefaultKeyGenerationService {
    constructor(cryptoFunctionService) {
        this.cryptoFunctionService = cryptoFunctionService;
    }
    createKey(bitLength) {
        return default_key_generation_service_awaiter(this, void 0, void 0, function* () {
            const key = yield this.cryptoFunctionService.aesGenerateKey(bitLength);
            return new SymmetricCryptoKey(key);
        });
    }
    createKeyWithPurpose(bitLength, purpose, salt) {
        return default_key_generation_service_awaiter(this, void 0, void 0, function* () {
            if (salt == null) {
                const bytes = yield this.cryptoFunctionService.randomBytes(32);
                salt = utils_Utils.fromBufferToUtf8(bytes.buffer);
            }
            const material = yield this.cryptoFunctionService.aesGenerateKey(bitLength);
            const key = yield this.cryptoFunctionService.hkdf(material, salt, purpose, 64, "sha256");
            return { salt, material, derivedKey: new SymmetricCryptoKey(key) };
        });
    }
    deriveKeyFromMaterial(material, salt, purpose) {
        return default_key_generation_service_awaiter(this, void 0, void 0, function* () {
            const key = yield this.cryptoFunctionService.hkdf(material, salt, purpose, 64, "sha256");
            return new SymmetricCryptoKey(key);
        });
    }
    deriveKeyFromPassword(password, salt, kdfConfig) {
        return default_key_generation_service_awaiter(this, void 0, void 0, function* () {
            if (typeof password === "string") {
                password = new TextEncoder().encode(password);
            }
            if (typeof salt === "string") {
                salt = new TextEncoder().encode(salt);
            }
            yield SdkLoadService.Ready;
            return new SymmetricCryptoKey(bitwarden_wasm_internal_bg/* PureCrypto */.IEs.derive_kdf_material(password, salt, kdfConfig.toSdkConfig()));
        });
    }
    stretchKey(key) {
        return default_key_generation_service_awaiter(this, void 0, void 0, function* () {
            // The key to be stretched is actually usually the output of a KDF, and not actually meant for AesCbc256_B64 encryption,
            // but has the same key length. Only 256-bit key materials should be stretched.
            if (key.inner().type != encryption_type_enum_EncryptionType.AesCbc256_B64) {
                throw new Error("Key passed into stretchKey is not a 256-bit key.");
            }
            const newKey = new Uint8Array(64);
            // Master key and pin key are always 32 bytes
            const encKey = yield this.cryptoFunctionService.hkdfExpand(key.inner().encryptionKey, "enc", 32, "sha256");
            const macKey = yield this.cryptoFunctionService.hkdfExpand(key.inner().encryptionKey, "mac", 32, "sha256");
            newKey.set(new Uint8Array(encKey));
            newKey.set(new Uint8Array(macKey), 32);
            return new SymmetricCryptoKey(newKey);
        });
    }
    deriveVaultExportKey(password, salt, kdfConfig) {
        return default_key_generation_service_awaiter(this, void 0, void 0, function* () {
            return yield this.stretchKey(yield this.deriveKeyFromPassword(password, salt, kdfConfig));
        });
    }
}

;// external "node-forge"
const external_node_forge_namespaceObject = require("node-forge");
;// ../../libs/common/src/key-management/crypto/dangerous/dangerous_duckduckgo_crypto.ts


/**
 * Decrypts a DuckDuckGo encstring, which is in the format of 2.B64IV|B64DATA|B64MAC, using AES-256-CBC for encryption and HMAC-SHA256 for authentication.
 * Note that this implementation does not use PKCS#7 padding, and the last CBC block is filled up with zeroes when decrypting, leading us to guess where
 * the contents end.
 */
function DANGEROUS_aesDecryptDuckDuckGoNoPaddingAes256CbcHmac(encstring, key) {
    // Parse the encstring
    const [, rest] = encstring.split(".", 2);
    const [ivB64, dataB64, macB64] = rest.split("|", 3);
    const [iv, data, mac] = [ivB64, dataB64, macB64].map((part) => Utils.fromB64ToArray(part));
    // Calculate the MAC and compare it. If the mac does not match, throw an error.
    // Note: The mac is over both IV and data
    const hmac = forge.hmac.create();
    hmac.start("sha256", Utils.fromArrayToByteString(key.authenticationKey));
    hmac.update(Utils.fromArrayToByteString(concatUint8Arrays(iv, data)));
    const expectedMac = Utils.fromByteStringToArray(hmac.digest().getBytes());
    if (!compareConstantTime(mac, expectedMac)) {
        throw new Error("MAC verification failed.");
    }
    // Decrypt the data
    const decryptor = forge.cipher.createDecipher("AES-CBC", Utils.fromArrayToByteString(key.encryptionKey));
    decryptor.start({ iv: Utils.fromArrayToByteString(iv) });
    decryptor.update(forge.util.createBuffer(Utils.fromArrayToByteString(data)));
    if (!decryptor.finish()) {
        throw new Error("Decryption failed.");
    }
    // PKCS#7 padding is not used. Therefore, the plaintext will look something like:
    // [DATA][DATA][DATA][PARTIAL], where data are full 16-byte blocks, and partial is the last
    // block, that contains up to 16 null bytes, along with a prefix of data, i.e:
    // [PARTIAL] = [1,2,3,4,5,0,0,0,0,0,0,0,0,0,0,0] (if the last block has 5 bytes of data)
    // We have to remove the trailing null bytes here.
    const decryptedBytes = Utils.fromByteStringToArray(decryptor.output.getBytes());
    let endIndex = decryptedBytes.length;
    while (endIndex > 0 && decryptedBytes[endIndex - 1] === 0) {
        endIndex--;
    }
    return decryptedBytes.slice(0, endIndex);
}
// Safely compare two values in a way that protects against timing attacks (Double HMAC Verification).
// ref: https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/february/double-hmac-verification/
// ref: https://paragonie.com/blog/2015/11/preventing-timing-attacks-on-string-comparison-with-double-hmac-strategy
function compareConstantTime(a, b) {
    const rand = self.crypto.getRandomValues(new Uint8Array(32));
    const hmac = forge.hmac.create();
    hmac.start("sha256", Utils.fromArrayToByteString(rand));
    hmac.update(Utils.fromArrayToByteString(a));
    const mac1 = hmac.digest().getBytes();
    hmac.start("sha256", Utils.fromArrayToByteString(rand));
    hmac.update(Utils.fromArrayToByteString(b));
    const mac2 = hmac.digest().getBytes();
    const equals = mac1 === mac2;
    return equals;
}
function concatUint8Arrays(a, b) {
    const result = new Uint8Array(a.length + b.length);
    result.set(a, 0);
    result.set(b, a.length);
    return result;
}

;// ../../libs/common/src/key-management/crypto/dangerous/dangerous_lastpass_crypto.ts


/**
 * Decrypts data using AES-ECB with the given key.
 * This is used for decrypting LastPass imports, which use AES-ECB without an IV.
 * ECB is extremely dangerous: https://words.filippo.io/the-ecb-penguin/
 *
 * ⚠️️ HAZMAT WARNING ⚠️️: AES-ECB is not a secure encryption mode and allows both tampering and
 * leaks large amounts of information. DO NOT USE THIS FOR ANYTHING ELSE THAN DECRYPTING LASTPASS
 * IMPORTS.
 */
function DANGEROUS_aesEcbDecryptLastpassImport(data, key) {
    const decryptor = forge.cipher.createDecipher("AES-ECB", Utils.fromArrayToByteString(key));
    decryptor.start();
    decryptor.update(forge.util.createBuffer(Utils.fromArrayToByteString(data)));
    if (!decryptor.finish()) {
        throw new Error("AES-ECB decryption failed.");
    }
    return Utils.fromByteStringToArray(decryptor.output.getBytes());
}
/**
 * Decrypts data using AES-CBC with the given key and IV.
 * This is used for decrypting LastPass imports, which use AES-CBC with a separate IV. No
 * MAC is performed, and this is vulnerable to tampering (xor malleability).
 *
 * ⚠️️ HAZMAT WARNING ⚠️️: AES-CBC without proper authentication allows tampering and should not be used
 * for new designs. DO NOT USE THIS FOR ANYTHING ELSE THAN DECRYPTING LASTPASS IMPORTS.
 */
function DANGEROUS_aesCbcDecryptLastpassImport(data, key, iv) {
    const decryptor = forge.cipher.createDecipher("AES-CBC", Utils.fromArrayToByteString(key));
    decryptor.start({ iv: Utils.fromArrayToByteString(iv) });
    decryptor.update(forge.util.createBuffer(Utils.fromArrayToByteString(data)));
    if (!decryptor.finish()) {
        throw new Error("AES-CBC decryption failed.");
    }
    return Utils.fromByteStringToArray(decryptor.output.getBytes());
}

;// ../../libs/common/src/key-management/crypto/dangerous/index.ts
// Provides legacy / compatibility crypto that should not be used by anything other than the external
// integration.



;// ../../libs/common/src/key-management/crypto/index.ts




;// ../../libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts
var encrypt_service_implementation_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};







class EncryptServiceImplementation {
    constructor(cryptoFunctionService, logService, logMacFailures) {
        this.cryptoFunctionService = cryptoFunctionService;
        this.logService = logService;
        this.logMacFailures = logMacFailures;
    }
    encryptString(plainValue, key) {
        return encrypt_service_implementation_awaiter(this, void 0, void 0, function* () {
            if (plainValue == null) {
                this.logService.warning("[EncryptService] WARNING: encryptString called with null value. Returning null, but this behavior is deprecated and will be removed.");
                return null;
            }
            yield SdkLoadService.Ready;
            return new enc_string_EncString(bitwarden_wasm_internal_bg/* PureCrypto */.IEs.symmetric_encrypt_string(plainValue, key.toEncoded()));
        });
    }
    encryptBytes(plainValue, key) {
        return encrypt_service_implementation_awaiter(this, void 0, void 0, function* () {
            yield SdkLoadService.Ready;
            return new enc_string_EncString(bitwarden_wasm_internal_bg/* PureCrypto */.IEs.symmetric_encrypt_bytes(plainValue, key.toEncoded()));
        });
    }
    encryptFileData(plainValue, key) {
        return encrypt_service_implementation_awaiter(this, void 0, void 0, function* () {
            yield SdkLoadService.Ready;
            return new EncArrayBuffer(bitwarden_wasm_internal_bg/* PureCrypto */.IEs.symmetric_encrypt_filedata(plainValue, key.toEncoded()));
        });
    }
    decryptString(encString, key) {
        return encrypt_service_implementation_awaiter(this, void 0, void 0, function* () {
            if (encString.encryptionType === encryption_type_enum_EncryptionType.AesCbc256_B64) {
                throw new Error("Decryption of AesCbc256_B64 encrypted data is disabled.");
            }
            yield SdkLoadService.Ready;
            return bitwarden_wasm_internal_bg/* PureCrypto */.IEs.symmetric_decrypt_string(encString.encryptedString, key.toEncoded());
        });
    }
    decryptBytes(encString, key) {
        return encrypt_service_implementation_awaiter(this, void 0, void 0, function* () {
            if (encString.encryptionType === encryption_type_enum_EncryptionType.AesCbc256_B64) {
                throw new Error("Decryption of AesCbc256_B64 encrypted data is disabled.");
            }
            yield SdkLoadService.Ready;
            return bitwarden_wasm_internal_bg/* PureCrypto */.IEs.symmetric_decrypt_bytes(encString.encryptedString, key.toEncoded());
        });
    }
    decryptFileData(encBuffer, key) {
        return encrypt_service_implementation_awaiter(this, void 0, void 0, function* () {
            if (encBuffer.encryptionType === encryption_type_enum_EncryptionType.AesCbc256_B64) {
                throw new Error("Decryption of AesCbc256_B64 encrypted data is disabled.");
            }
            yield SdkLoadService.Ready;
            return bitwarden_wasm_internal_bg/* PureCrypto */.IEs.symmetric_decrypt_filedata(encBuffer.buffer, key.toEncoded());
        });
    }
    wrapDecapsulationKey(decapsulationKeyPkcs8, wrappingKey) {
        return encrypt_service_implementation_awaiter(this, void 0, void 0, function* () {
            if (decapsulationKeyPkcs8 == null) {
                throw new Error("No decapsulation key provided for wrapping.");
            }
            if (wrappingKey == null) {
                throw new Error("No wrappingKey provided for wrapping.");
            }
            yield SdkLoadService.Ready;
            return new enc_string_EncString(bitwarden_wasm_internal_bg/* PureCrypto */.IEs.wrap_decapsulation_key(decapsulationKeyPkcs8, wrappingKey.toEncoded()));
        });
    }
    wrapEncapsulationKey(encapsulationKeySpki, wrappingKey) {
        return encrypt_service_implementation_awaiter(this, void 0, void 0, function* () {
            if (encapsulationKeySpki == null) {
                throw new Error("No encapsulation key provided for wrapping.");
            }
            if (wrappingKey == null) {
                throw new Error("No wrappingKey provided for wrapping.");
            }
            yield SdkLoadService.Ready;
            return new enc_string_EncString(bitwarden_wasm_internal_bg/* PureCrypto */.IEs.wrap_encapsulation_key(encapsulationKeySpki, wrappingKey.toEncoded()));
        });
    }
    wrapSymmetricKey(keyToBeWrapped, wrappingKey) {
        return encrypt_service_implementation_awaiter(this, void 0, void 0, function* () {
            if (keyToBeWrapped == null) {
                throw new Error("No keyToBeWrapped provided for wrapping.");
            }
            if (wrappingKey == null) {
                throw new Error("No wrappingKey provided for wrapping.");
            }
            yield SdkLoadService.Ready;
            return new enc_string_EncString(bitwarden_wasm_internal_bg/* PureCrypto */.IEs.wrap_symmetric_key(keyToBeWrapped.toEncoded(), wrappingKey.toEncoded()));
        });
    }
    unwrapDecapsulationKey(wrappedDecapsulationKey, wrappingKey) {
        return encrypt_service_implementation_awaiter(this, void 0, void 0, function* () {
            if (wrappedDecapsulationKey == null) {
                throw new Error("No wrappedDecapsulationKey provided for unwrapping.");
            }
            if (wrappingKey == null) {
                throw new Error("No wrappingKey provided for unwrapping.");
            }
            if (wrappedDecapsulationKey.encryptionType === encryption_type_enum_EncryptionType.AesCbc256_B64) {
                throw new Error("Decryption of AesCbc256_B64 encrypted data is disabled.");
            }
            yield SdkLoadService.Ready;
            return bitwarden_wasm_internal_bg/* PureCrypto */.IEs.unwrap_decapsulation_key(wrappedDecapsulationKey.encryptedString, wrappingKey.toEncoded());
        });
    }
    unwrapEncapsulationKey(wrappedEncapsulationKey, wrappingKey) {
        return encrypt_service_implementation_awaiter(this, void 0, void 0, function* () {
            if (wrappedEncapsulationKey == null) {
                throw new Error("No wrappedEncapsulationKey provided for unwrapping.");
            }
            if (wrappingKey == null) {
                throw new Error("No wrappingKey provided for unwrapping.");
            }
            if (wrappedEncapsulationKey.encryptionType === encryption_type_enum_EncryptionType.AesCbc256_B64) {
                throw new Error("Decryption of AesCbc256_B64 encrypted data is disabled.");
            }
            yield SdkLoadService.Ready;
            return bitwarden_wasm_internal_bg/* PureCrypto */.IEs.unwrap_encapsulation_key(wrappedEncapsulationKey.encryptedString, wrappingKey.toEncoded());
        });
    }
    unwrapSymmetricKey(keyToBeUnwrapped, wrappingKey) {
        return encrypt_service_implementation_awaiter(this, void 0, void 0, function* () {
            if (keyToBeUnwrapped == null) {
                throw new Error("No keyToBeUnwrapped provided for unwrapping.");
            }
            if (wrappingKey == null) {
                throw new Error("No wrappingKey provided for unwrapping.");
            }
            if (keyToBeUnwrapped.encryptionType === encryption_type_enum_EncryptionType.AesCbc256_B64) {
                throw new Error("Decryption of AesCbc256_B64 encrypted data is disabled.");
            }
            yield SdkLoadService.Ready;
            return new SymmetricCryptoKey(bitwarden_wasm_internal_bg/* PureCrypto */.IEs.unwrap_symmetric_key(keyToBeUnwrapped.encryptedString, wrappingKey.toEncoded()));
        });
    }
    hash(value, algorithm) {
        return encrypt_service_implementation_awaiter(this, void 0, void 0, function* () {
            const hashArray = yield this.cryptoFunctionService.hash(value, algorithm);
            return utils_Utils.fromBufferToB64(hashArray);
        });
    }
    encapsulateKeyUnsigned(sharedKey, encapsulationKey) {
        return encrypt_service_implementation_awaiter(this, void 0, void 0, function* () {
            if (sharedKey == null) {
                throw new Error("No sharedKey provided for encapsulation");
            }
            if (encapsulationKey == null) {
                throw new Error("No encapsulationKey provided for encapsulation");
            }
            yield SdkLoadService.Ready;
            return new enc_string_EncString(bitwarden_wasm_internal_bg/* PureCrypto */.IEs.encapsulate_key_unsigned(sharedKey.toEncoded(), encapsulationKey));
        });
    }
    decapsulateKeyUnsigned(encryptedSharedKey, decapsulationKey) {
        return encrypt_service_implementation_awaiter(this, void 0, void 0, function* () {
            if (encryptedSharedKey == null) {
                throw new Error("No encryptedSharedKey provided for decapsulation");
            }
            if (decapsulationKey == null) {
                throw new Error("No decapsulationKey provided for decapsulation");
            }
            yield SdkLoadService.Ready;
            const keyBytes = bitwarden_wasm_internal_bg/* PureCrypto */.IEs.decapsulate_key_unsigned(encryptedSharedKey.encryptedString, decapsulationKey);
            return new SymmetricCryptoKey(keyBytes);
        });
    }
}

;// ../../libs/common/src/auth/models/request/update-devices-trust.request.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

class UpdateDevicesTrustRequest extends SecretVerificationRequest {
}
class DeviceKeysUpdateRequest {
}
class OtherDeviceKeysUpdateRequest extends DeviceKeysUpdateRequest {
}

;// ../../libs/common/src/key-management/device-trust/services/device-trust.service.implementation.ts
var device_trust_service_implementation_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore








/** Uses disk storage so that the device key can persist after log out and tab removal. */
const device_trust_service_implementation_DEVICE_KEY = new UserKeyDefinition(DEVICE_TRUST_DISK_LOCAL, "deviceKey", {
    deserializer: (deviceKey) => deviceKey ? SymmetricCryptoKey.fromJSON(deviceKey) : null,
    clearOn: [], // Device key is needed to log back into device, so we can't clear it automatically during lock or logout
    cleanupDelayMs: 0,
    debug: {
        enableRetrievalLogging: true,
        enableUpdateLogging: true,
    },
});
/** Uses disk storage so that the shouldTrustDevice bool can persist across login. */
const device_trust_service_implementation_SHOULD_TRUST_DEVICE = new UserKeyDefinition(DEVICE_TRUST_DISK_LOCAL, "shouldTrustDevice", {
    deserializer: (shouldTrustDevice) => shouldTrustDevice,
    clearOn: [], // Need to preserve the user setting, so we can't clear it automatically during lock or logout
});
class DeviceTrustService {
    constructor(keyGenerationService, cryptoFunctionService, keyService, encryptService, appIdService, devicesApiService, i18nService, platformUtilsService, stateProvider, secureStorageService, userDecryptionOptionsService, logService, configService, accountService) {
        this.keyGenerationService = keyGenerationService;
        this.cryptoFunctionService = cryptoFunctionService;
        this.keyService = keyService;
        this.encryptService = encryptService;
        this.appIdService = appIdService;
        this.devicesApiService = devicesApiService;
        this.i18nService = i18nService;
        this.platformUtilsService = platformUtilsService;
        this.stateProvider = stateProvider;
        this.secureStorageService = secureStorageService;
        this.userDecryptionOptionsService = userDecryptionOptionsService;
        this.logService = logService;
        this.configService = configService;
        this.accountService = accountService;
        this.platformSupportsSecureStorage = this.platformUtilsService.supportsSecureStorage();
        this.deviceKeySecureStorageKey = "_deviceKey";
        // Observable emission is used to trigger a toast in consuming components
        this.deviceTrustedSubject = new external_rxjs_namespaceObject.Subject();
        this.deviceTrusted$ = this.deviceTrustedSubject.asObservable();
        this.supportsDeviceTrust$ = this.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.switchMap)((account) => {
            if (account == null) {
                return [false];
            }
            return this.userDecryptionOptionsService.userDecryptionOptionsById$(account.id).pipe((0,external_rxjs_namespaceObject.map)((options) => {
                return (options === null || options === void 0 ? void 0 : options.trustedDeviceOption) != null;
            }));
        }));
    }
    supportsDeviceTrustByUserId$(userId) {
        return this.userDecryptionOptionsService.userDecryptionOptionsById$(userId).pipe((0,external_rxjs_namespaceObject.map)((options) => {
            return (options === null || options === void 0 ? void 0 : options.trustedDeviceOption) != null;
        }));
    }
    /**
     * @description Retrieves the users choice to trust the device which can only happen after decryption
     * Note: this value should only be used once and then reset
     */
    getShouldTrustDevice(userId) {
        return device_trust_service_implementation_awaiter(this, void 0, void 0, function* () {
            if (!userId) {
                throw new Error("UserId is required. Cannot get should trust device.");
            }
            const shouldTrustDevice = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.stateProvider.getUserState$(device_trust_service_implementation_SHOULD_TRUST_DEVICE, userId));
            return shouldTrustDevice;
        });
    }
    setShouldTrustDevice(userId, value) {
        return device_trust_service_implementation_awaiter(this, void 0, void 0, function* () {
            if (!userId) {
                throw new Error("UserId is required. Cannot set should trust device.");
            }
            yield this.stateProvider.setUserState(device_trust_service_implementation_SHOULD_TRUST_DEVICE, value, userId);
        });
    }
    trustDeviceIfRequired(userId) {
        return device_trust_service_implementation_awaiter(this, void 0, void 0, function* () {
            if (!userId) {
                throw new Error("UserId is required. Cannot trust device if required.");
            }
            const shouldTrustDevice = yield this.getShouldTrustDevice(userId);
            if (shouldTrustDevice) {
                yield this.trustDevice(userId);
                // reset the trust choice
                yield this.setShouldTrustDevice(userId, null);
            }
        });
    }
    trustDevice(userId) {
        return device_trust_service_implementation_awaiter(this, void 0, void 0, function* () {
            if (!userId) {
                throw new Error("UserId is required. Cannot trust device.");
            }
            // Attempt to get user key
            const userKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.userKey$(userId));
            // If user key is not found, throw error
            if (!userKey) {
                throw new Error("User symmetric key not found");
            }
            // Generate deviceKey
            const deviceKey = yield this.makeDeviceKey();
            // Generate asymmetric RSA key pair: devicePrivateKey, devicePublicKey
            const [devicePublicKey, devicePrivateKey] = yield this.cryptoFunctionService.rsaGenerateKeyPair(2048);
            const [devicePublicKeyEncryptedUserKey, userKeyEncryptedDevicePublicKey, deviceKeyEncryptedDevicePrivateKey,] = yield Promise.all([
                // Encrypt user key with the DevicePublicKey
                this.encryptService.encapsulateKeyUnsigned(userKey, devicePublicKey),
                // Encrypt devicePublicKey with user key
                this.encryptService.wrapEncapsulationKey(devicePublicKey, userKey),
                // Encrypt devicePrivateKey with deviceKey
                this.encryptService.wrapDecapsulationKey(devicePrivateKey, deviceKey),
            ]);
            // Send encrypted keys to server
            const deviceIdentifier = yield this.appIdService.getAppId();
            const deviceResponse = yield this.devicesApiService.updateTrustedDeviceKeys(deviceIdentifier, devicePublicKeyEncryptedUserKey.encryptedString, userKeyEncryptedDevicePublicKey.encryptedString, deviceKeyEncryptedDevicePrivateKey.encryptedString);
            // store device key in local/secure storage if enc keys posted to server successfully
            yield this.setDeviceKey(userId, deviceKey);
            // This emission will be picked up by consuming components to handle displaying a toast to the user
            this.deviceTrustedSubject.next();
            return deviceResponse;
        });
    }
    getRotatedData(oldUserKey, newUserKey, userId) {
        return device_trust_service_implementation_awaiter(this, void 0, void 0, function* () {
            if (!userId) {
                throw new Error("UserId is required. Cannot get rotated data.");
            }
            if (!oldUserKey) {
                throw new Error("Old user key is required. Cannot get rotated data.");
            }
            if (!newUserKey) {
                throw new Error("New user key is required. Cannot get rotated data.");
            }
            const devices = yield this.devicesApiService.getDevices();
            const devicesToUntrust = [];
            const rotatedData = yield Promise.all(devices.data
                .filter((device) => device.isTrusted)
                .map((device) => device_trust_service_implementation_awaiter(this, void 0, void 0, function* () {
                const publicKey = yield this.encryptService.unwrapEncapsulationKey(new enc_string_EncString(device.encryptedPublicKey), oldUserKey);
                if (!publicKey) {
                    // Device was trusted but encryption is broken. This should be untrusted
                    devicesToUntrust.push(device.id);
                    return null;
                }
                const newEncryptedPublicKey = yield this.encryptService.wrapEncapsulationKey(publicKey, newUserKey);
                const newEncryptedUserKey = yield this.encryptService.encapsulateKeyUnsigned(newUserKey, publicKey);
                const newRotateableKeySet = new RotateableKeySet(newEncryptedUserKey, newEncryptedPublicKey);
                const request = new OtherDeviceKeysUpdateRequest();
                request.encryptedPublicKey = newRotateableKeySet.encryptedPublicKey.encryptedString;
                request.encryptedUserKey = newRotateableKeySet.encapsulatedDownstreamKey.encryptedString;
                request.deviceId = device.id;
                return request;
            }))
                .filter((otherDeviceKeysUpdateRequest) => otherDeviceKeysUpdateRequest != null));
            if (rotatedData.length > 0) {
                this.logService.info("[Device trust rotation] Distrusting devices that failed to decrypt.");
                yield this.devicesApiService.untrustDevices(devicesToUntrust);
            }
            return rotatedData;
        });
    }
    rotateDevicesTrust(userId, newUserKey, masterPasswordHash) {
        return device_trust_service_implementation_awaiter(this, void 0, void 0, function* () {
            this.logService.info("[Device trust rotation] Rotating device trust...");
            if (!userId) {
                throw new Error("UserId is required. Cannot rotate device's trust.");
            }
            const currentDeviceKey = yield this.getDeviceKey(userId);
            if (currentDeviceKey == null) {
                // If the current device doesn't have a device key available to it, then we can't
                // rotate any trust at all, so early return.
                this.logService.info("[Device trust rotation] No device key available to rotate trust!");
                return;
            }
            // At this point of rotating their keys, they should still have their old user key in state
            const oldUserKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.userKey$(userId));
            if (oldUserKey == newUserKey) {
                this.logService.info("[Device trust rotation] Old user key is the same as the new user key.");
            }
            const deviceIdentifier = yield this.appIdService.getAppId();
            const secretVerificationRequest = new SecretVerificationRequest();
            secretVerificationRequest.masterPasswordHash = masterPasswordHash;
            // Get the keys that are used in rotating a devices keys from the server
            const currentDeviceKeys = yield this.devicesApiService.getDeviceKeys(deviceIdentifier);
            // Decrypt the existing device public key with the old user key
            const decryptedDevicePublicKey = yield this.encryptService.unwrapEncapsulationKey(currentDeviceKeys.encryptedPublicKey, oldUserKey);
            // Encrypt the brand new user key with the now-decrypted public key for the device
            const encryptedNewUserKey = yield this.encryptService.encapsulateKeyUnsigned(newUserKey, decryptedDevicePublicKey);
            // Re-encrypt the device public key with the new user key
            const encryptedDevicePublicKey = yield this.encryptService.wrapEncapsulationKey(decryptedDevicePublicKey, newUserKey);
            const currentDeviceUpdateRequest = new DeviceKeysUpdateRequest();
            currentDeviceUpdateRequest.encryptedUserKey = encryptedNewUserKey.encryptedString;
            currentDeviceUpdateRequest.encryptedPublicKey = encryptedDevicePublicKey.encryptedString;
            // TODO: For device management, allow this method to take an array of device ids that can be looped over and individually rotated
            // then it can be added to trustRequest.otherDevices.
            const trustRequest = new UpdateDevicesTrustRequest();
            trustRequest.masterPasswordHash = masterPasswordHash;
            trustRequest.currentDevice = currentDeviceUpdateRequest;
            trustRequest.otherDevices = [];
            this.logService.info("[Device trust rotation] Posting device trust update with current device:", deviceIdentifier);
            yield this.devicesApiService.updateTrust(trustRequest, deviceIdentifier);
            this.logService.info("[Device trust rotation] Device trust update posted successfully.");
        });
    }
    getDeviceKey(userId) {
        return device_trust_service_implementation_awaiter(this, void 0, void 0, function* () {
            if (!userId) {
                throw new Error("UserId is required. Cannot get device key.");
            }
            try {
                if (this.platformSupportsSecureStorage) {
                    const deviceKeyB64 = yield this.secureStorageService.get(`${userId}${this.deviceKeySecureStorageKey}`, this.getSecureStorageOptions(userId));
                    const deviceKey = SymmetricCryptoKey.fromJSON(deviceKeyB64);
                    return deviceKey;
                }
                const deviceKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.stateProvider.getUserState$(device_trust_service_implementation_DEVICE_KEY, userId));
                return deviceKey;
            }
            catch (e) {
                this.logService.error("Failed to get device key", e);
            }
        });
    }
    setDeviceKey(userId, deviceKey) {
        return device_trust_service_implementation_awaiter(this, void 0, void 0, function* () {
            if (!userId) {
                throw new Error("UserId is required. Cannot set device key.");
            }
            try {
                if (this.platformSupportsSecureStorage) {
                    yield this.secureStorageService.save(`${userId}${this.deviceKeySecureStorageKey}`, deviceKey, this.getSecureStorageOptions(userId));
                    return;
                }
                yield this.stateProvider.setUserState(device_trust_service_implementation_DEVICE_KEY, deviceKey === null || deviceKey === void 0 ? void 0 : deviceKey.toJSON(), userId);
            }
            catch (e) {
                this.logService.error("Failed to set device key", e);
            }
        });
    }
    makeDeviceKey() {
        return device_trust_service_implementation_awaiter(this, void 0, void 0, function* () {
            // Create 512-bit device key
            const deviceKey = (yield this.keyGenerationService.createKey(512));
            return deviceKey;
        });
    }
    decryptUserKeyWithDeviceKey(userId, encryptedDevicePrivateKey, encryptedUserKey, deviceKey) {
        return device_trust_service_implementation_awaiter(this, void 0, void 0, function* () {
            if (!userId) {
                throw new Error("UserId is required. Cannot decrypt user key with device key.");
            }
            if (!encryptedDevicePrivateKey) {
                throw new Error("Encrypted device private key is required. Cannot decrypt user key with device key.");
            }
            if (!encryptedUserKey) {
                throw new Error("Encrypted user key is required. Cannot decrypt user key with device key.");
            }
            if (!deviceKey) {
                // User doesn't have a device key anymore so device is untrusted
                return null;
            }
            try {
                // attempt to decrypt encryptedDevicePrivateKey with device key
                const devicePrivateKey = yield this.encryptService.unwrapDecapsulationKey(encryptedDevicePrivateKey, deviceKey);
                // Attempt to decrypt encryptedUserDataKey with devicePrivateKey
                const userKey = yield this.encryptService.decapsulateKeyUnsigned(new enc_string_EncString(encryptedUserKey.encryptedString), devicePrivateKey);
                return userKey;
                // FIXME: Remove when updating file. Eslint update
                // eslint-disable-next-line @typescript-eslint/no-unused-vars
            }
            catch (e) {
                // If either decryption effort fails, we want to remove the device key
                this.logService.error("Failed to decrypt using device key. Removing device key.");
                yield this.setDeviceKey(userId, null);
                return null;
            }
        });
    }
    recordDeviceTrustLoss() {
        return device_trust_service_implementation_awaiter(this, void 0, void 0, function* () {
            const deviceIdentifier = yield this.appIdService.getAppId();
            yield this.devicesApiService.postDeviceTrustLoss(deviceIdentifier);
        });
    }
    getSecureStorageOptions(userId) {
        return {
            storageLocation: StorageLocationEnum.Disk,
            useSecureStorage: true,
            userId: userId,
        };
    }
}

;// ../../libs/common/src/key-management/encrypted-migrator/migrations/minimum-kdf-migration.ts
var minimum_kdf_migration_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// eslint-disable-next-line no-restricted-imports



/**
 * @internal
 * This migrator ensures the user's account has a minimum PBKDF2 iteration count.
 * It will update the entire account, logging out old clients if necessary.
 */
class MinimumKdfMigration {
    constructor(kdfConfigService, changeKdfService, logService, configService, masterPasswordService, syncService) {
        this.kdfConfigService = kdfConfigService;
        this.changeKdfService = changeKdfService;
        this.logService = logService;
        this.configService = configService;
        this.masterPasswordService = masterPasswordService;
        this.syncService = syncService;
    }
    runMigrations(userId, masterPassword) {
        return minimum_kdf_migration_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(userId, "userId");
            assertNonNullish(masterPassword, "masterPassword");
            this.logService.info(`[MinimumKdfMigration] Updating user ${userId} to minimum PBKDF2 iteration count ${PBKDF2KdfConfig.ITERATIONS.defaultValue}`);
            yield this.changeKdfService.updateUserKdfParams(masterPassword, new PBKDF2KdfConfig(PBKDF2KdfConfig.ITERATIONS.min), userId);
            yield this.kdfConfigService.setKdfConfig(userId, new PBKDF2KdfConfig(PBKDF2KdfConfig.ITERATIONS.min));
        });
    }
    needsMigration(userId) {
        return minimum_kdf_migration_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(userId, "userId");
            if (!(yield this.masterPasswordService.userHasMasterPassword(userId))) {
                return "noMigrationNeeded";
            }
            if (!(yield this.localStateNeedsMigration(userId))) {
                return "noMigrationNeeded";
            }
            if (!(yield this.configService.getFeatureFlag(feature_flag_enum_FeatureFlag.ForceUpdateKDFSettings))) {
                return "noMigrationNeeded";
            }
            // This will be replaced by a separate API call that provides the user decryption options.
            // This may have a race condition with account switching, since runMigrations is bound to a user-id, but
            // sync-service takes the active user-id from state. It ensures we have the latest data from the server.
            // It is possible that the current client was offline while the migration happened. This would cause the
            // local state to still have the old KDF values and prompt another time.
            yield this.syncService.fullSync(false);
            if (!(yield this.localStateNeedsMigration(userId))) {
                this.logService.info(`[MinimumKdfMigration] After syncing, user ${userId} does not need migration anymore. This means the migration was likely already performed on another client!`);
                return "noMigrationNeeded";
            }
            else {
                return "needsMigrationWithMasterPassword";
            }
        });
    }
    localStateNeedsMigration(userId) {
        return minimum_kdf_migration_awaiter(this, void 0, void 0, function* () {
            const kdfConfig = yield this.kdfConfigService.getKdfConfig(userId);
            // Only PBKDF2 users below the minimum iteration count need migration
            return (kdfConfig.kdfType === kdf_type_enum_KdfType.PBKDF2_SHA256 &&
                kdfConfig.iterations < PBKDF2KdfConfig.ITERATIONS.min);
        });
    }
}

;// ../../libs/common/src/key-management/encrypted-migrator/default-encrypted-migrator.ts
var default_encrypted_migrator_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};


class DefaultEncryptedMigrator {
    constructor(kdfConfigService, changeKdfService, logService, configService, masterPasswordService, syncService) {
        this.kdfConfigService = kdfConfigService;
        this.changeKdfService = changeKdfService;
        this.logService = logService;
        this.configService = configService;
        this.masterPasswordService = masterPasswordService;
        this.syncService = syncService;
        this.migrations = [];
        this.isRunningMigration = false;
        // Register migrations here
        this.migrations.push({
            name: "Minimum PBKDF2 Iteration Count Migration",
            migration: new MinimumKdfMigration(kdfConfigService, changeKdfService, logService, configService, masterPasswordService, syncService),
        });
    }
    runMigrations(userId, masterPassword) {
        return default_encrypted_migrator_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(userId, "userId");
            // Ensure that the requirements for running all migrations are met
            const needsMigration = yield this.needsMigrations(userId);
            if (needsMigration === "noMigrationNeeded") {
                return;
            }
            else if (needsMigration === "needsMigrationWithMasterPassword" && masterPassword == null) {
                // If a migration needs a password, but none is provided, the migrations are skipped. If a manual caller
                // during a login / unlock flow calls without a master password in a login / unlock strategy that has no
                // password, such as biometric unlock, the migrations are skipped.
                //
                // The fallback to this, the encrypted migrations scheduler, will first check if a migration needs a password
                // and then prompt the user. If the user enters their password, runMigrations is called again with the password.
                return;
            }
            try {
                // No concurrent migrations allowed, so acquire a service-wide lock
                if (this.isRunningMigration) {
                    return;
                }
                this.isRunningMigration = true;
                // Run all migrations sequentially in the order they were registered
                this.logService.mark("[Encrypted Migrator] Start");
                this.logService.info(`[Encrypted Migrator] Starting migrations for user: ${userId}`);
                let ranMigration = false;
                for (const { name, migration } of this.migrations) {
                    if ((yield migration.needsMigration(userId)) !== "noMigrationNeeded") {
                        this.logService.info(`[Encrypted Migrator] Running migration: ${name}`);
                        const start = performance.now();
                        yield migration.runMigrations(userId, masterPassword);
                        this.logService.measure(start, "[Encrypted Migrator]", name, "ExecutionTime");
                        ranMigration = true;
                    }
                }
                this.logService.mark("[Encrypted Migrator] Finish");
                this.logService.info(`[Encrypted Migrator] Completed migrations for user: ${userId}`);
                if (ranMigration) {
                    yield this.syncService.fullSync(true);
                }
            }
            catch (error) {
                this.logService.error(`[Encrypted Migrator] Error running migrations for user: ${userId}`, error);
                throw error; // Re-throw the error to be handled by the caller
            }
            finally {
                this.isRunningMigration = false;
            }
        });
    }
    needsMigrations(userId) {
        return default_encrypted_migrator_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(userId, "userId");
            const migrationRequirements = yield Promise.all(this.migrations.map((_a) => default_encrypted_migrator_awaiter(this, [_a], void 0, function* ({ migration }) { return migration.needsMigration(userId); })));
            if (migrationRequirements.includes("needsMigrationWithMasterPassword")) {
                return "needsMigrationWithMasterPassword";
            }
            else if (migrationRequirements.includes("needsMigration")) {
                return "needsMigration";
            }
            else {
                return "noMigrationNeeded";
            }
        });
    }
    isRunningMigrations() {
        return this.isRunningMigration;
    }
}

;// ../../libs/common/src/key-management/kdf/change-kdf-api.service.ts
var change_kdf_api_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
/**
 * @internal
 */
class DefaultChangeKdfApiService {
    constructor(apiService) {
        this.apiService = apiService;
    }
    updateUserKdfParams(request) {
        return change_kdf_api_service_awaiter(this, void 0, void 0, function* () {
            return this.apiService.send("POST", "/accounts/kdf", request, true, false);
        });
    }
}

;// ../../libs/common/src/auth/models/request/password.request.ts

class PasswordRequest extends SecretVerificationRequest {
    // This will eventually be changed to be an actual constructor, once all callers are updated.
    // https://bitwarden.atlassian.net/browse/PM-23234
    static newConstructor(currentMasterPasswordAuthenticationHash, newAuthenticationData, newUnlockData, newMasterPasswordHint) {
        const request = new PasswordRequest();
        request.masterPasswordHash = currentMasterPasswordAuthenticationHash;
        request.newMasterPasswordHash = newAuthenticationData.masterPasswordAuthenticationHash;
        request.key = newUnlockData.masterKeyWrappedUserKey;
        request.authenticationData = newAuthenticationData;
        request.unlockData = newUnlockData;
        request.masterPasswordHint = newMasterPasswordHint;
        return request;
    }
}

;// ../../libs/common/src/models/request/kdf.request.ts

class KdfRequest extends PasswordRequest {
    constructor(authenticationData, unlockData) {
        super();
        // Note, this init code should be in the super constructor, once PasswordRequest's constructor is updated.
        this.newMasterPasswordHash = authenticationData.masterPasswordAuthenticationHash;
        this.key = unlockData.masterKeyWrappedUserKey;
        this.authenticationData = authenticationData;
        this.unlockData = unlockData;
    }
}

;// ../../libs/common/src/key-management/kdf/change-kdf.service.ts
var change_kdf_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __addDisposableResource = (undefined && undefined.__addDisposableResource) || function (env, value, async) {
    if (value !== null && value !== void 0) {
        if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
        var dispose, inner;
        if (async) {
            if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
            dispose = value[Symbol.asyncDispose];
        }
        if (dispose === void 0) {
            if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
            dispose = value[Symbol.dispose];
            if (async) inner = dispose;
        }
        if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
        if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
        env.stack.push({ value: value, dispose: dispose, async: async });
    }
    else if (async) {
        env.stack.push({ async: true });
    }
    return value;
};
var __disposeResources = (undefined && undefined.__disposeResources) || (function (SuppressedError) {
    return function (env) {
        function fail(e) {
            env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
            env.hasError = true;
        }
        var r, s = 0;
        function next() {
            while (r = env.stack.pop()) {
                try {
                    if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
                    if (r.dispose) {
                        var result = r.dispose.call(r.value);
                        if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
                    }
                    else s |= 1;
                }
                catch (e) {
                    fail(e);
                }
            }
            if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
            if (env.hasError) throw env.error;
        }
        return next();
    };
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
    var e = new Error(message);
    return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
});





class DefaultChangeKdfService {
    constructor(changeKdfApiService, sdkService, keyService, masterPasswordService, kdfConfigService) {
        this.changeKdfApiService = changeKdfApiService;
        this.sdkService = sdkService;
        this.keyService = keyService;
        this.masterPasswordService = masterPasswordService;
        this.kdfConfigService = kdfConfigService;
    }
    updateUserKdfParams(masterPassword, kdf, userId) {
        return change_kdf_service_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(masterPassword, "masterPassword");
            assertNonNullish(kdf, "kdf");
            assertNonNullish(userId, "userId");
            const updateKdfResult = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkService.userClient$(userId).pipe((0,external_rxjs_namespaceObject.map)((sdk) => {
                const env_1 = { stack: [], error: void 0, hasError: false };
                try {
                    if (!sdk) {
                        throw new Error("SDK not available");
                    }
                    const ref = __addDisposableResource(env_1, sdk.take(), false);
                    const updateKdfResponse = ref.value
                        .crypto()
                        .make_update_kdf(masterPassword, kdf.toSdkConfig());
                    return updateKdfResponse;
                }
                catch (e_1) {
                    env_1.error = e_1;
                    env_1.hasError = true;
                }
                finally {
                    __disposeResources(env_1);
                }
            })));
            const authenticationData = fromSdkAuthenticationData(updateKdfResult.masterPasswordAuthenticationData);
            const unlockData = MasterPasswordUnlockData.fromSdk(updateKdfResult.masterPasswordUnlockData);
            const oldAuthenticationData = fromSdkAuthenticationData(updateKdfResult.oldMasterPasswordAuthenticationData);
            const request = new KdfRequest(authenticationData, unlockData);
            request.authenticateWith(oldAuthenticationData);
            yield this.changeKdfApiService.updateUserKdfParams(request);
            // Update the locally stored master key and hash, so that UV, etc. still works
            const masterKey = yield this.keyService.makeMasterKey(masterPassword, unlockData.salt, unlockData.kdf);
            yield this.masterPasswordService.setMasterKey(masterKey, userId);
            yield this.masterPasswordService.setMasterPasswordUnlockData(unlockData, userId);
            yield this.masterPasswordService.setMasterKeyEncryptedUserKey(new enc_string_EncString(unlockData.masterKeyWrappedUserKey), userId);
            yield this.kdfConfigService.setKdfConfig(userId, kdf);
        });
    }
}

;// ../../libs/common/src/models/request/keys.request.ts
class KeysRequest {
    constructor(publicKey, encryptedPrivateKey) {
        this.publicKey = publicKey;
        this.encryptedPrivateKey = encryptedPrivateKey;
    }
}

;// ../../libs/common/src/key-management/key-connector/models/key-connector-user-key.request.ts
class KeyConnectorUserKeyRequest {
    constructor(key) {
        this.key = key;
    }
}

;// ../../libs/common/src/key-management/key-connector/models/set-key-connector-key.request.ts
// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop.
// eslint-disable-next-line no-restricted-imports

class SetKeyConnectorKeyRequest {
    constructor(key, kdfConfig, orgIdentifier, keys) {
        this.key = key;
        this.kdf = kdfConfig.kdfType;
        this.kdfIterations = kdfConfig.iterations;
        if (kdfConfig.kdfType === kdf_type_enum_KdfType.Argon2id) {
            this.kdfMemory = kdfConfig.memory;
            this.kdfParallelism = kdfConfig.parallelism;
        }
        this.orgIdentifier = orgIdentifier;
        this.keys = keys;
    }
}

;// ../../libs/common/src/key-management/key-connector/services/key-connector.service.ts
var key_connector_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var key_connector_service_addDisposableResource = (undefined && undefined.__addDisposableResource) || function (env, value, async) {
    if (value !== null && value !== void 0) {
        if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
        var dispose, inner;
        if (async) {
            if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
            dispose = value[Symbol.asyncDispose];
        }
        if (dispose === void 0) {
            if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
            dispose = value[Symbol.dispose];
            if (async) inner = dispose;
        }
        if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
        if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
        env.stack.push({ value: value, dispose: dispose, async: async });
    }
    else if (async) {
        env.stack.push({ async: true });
    }
    return value;
};
var key_connector_service_disposeResources = (undefined && undefined.__disposeResources) || (function (SuppressedError) {
    return function (env) {
        function fail(e) {
            env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
            env.hasError = true;
        }
        var r, s = 0;
        function next() {
            while (r = env.stack.pop()) {
                try {
                    if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
                    if (r.dispose) {
                        var result = r.dispose.call(r.value);
                        if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
                    }
                    else s |= 1;
                }
                catch (e) {
                    fail(e);
                }
            }
            if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
            if (env.hasError) throw env.error;
        }
        return next();
    };
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
    var e = new Error(message);
    return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
});
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop.
// eslint-disable-next-line no-restricted-imports










const USES_KEY_CONNECTOR = new UserKeyDefinition(KEY_CONNECTOR_DISK, "usesKeyConnector", {
    deserializer: (usesKeyConnector) => usesKeyConnector,
    clearOn: ["logout"],
    cleanupDelayMs: 0,
});
const NEW_SSO_USER_KEY_CONNECTOR_CONVERSION = new UserKeyDefinition(KEY_CONNECTOR_DISK, "newSsoUserKeyConnectorConversion", {
    deserializer: (conversion) => conversion == null
        ? null
        : {
            kdfConfig: conversion.kdfConfig.kdfType === kdf_type_enum_KdfType.PBKDF2_SHA256
                ? PBKDF2KdfConfig.fromJSON(conversion.kdfConfig)
                : Argon2KdfConfig.fromJSON(conversion.kdfConfig),
            keyConnectorUrl: conversion.keyConnectorUrl,
            organizationId: conversion.organizationId,
        },
    clearOn: ["logout"],
    cleanupDelayMs: 0,
});
class KeyConnectorService {
    constructor(accountService, masterPasswordService, keyService, apiService, tokenService, logService, organizationService, keyGenerationService, logoutCallback, stateProvider, configService, registerSdkService, accountCryptographicStateService, sdkService, userDecryptionOptionsService) {
        this.masterPasswordService = masterPasswordService;
        this.keyService = keyService;
        this.apiService = apiService;
        this.tokenService = tokenService;
        this.logService = logService;
        this.organizationService = organizationService;
        this.keyGenerationService = keyGenerationService;
        this.logoutCallback = logoutCallback;
        this.stateProvider = stateProvider;
        this.configService = configService;
        this.registerSdkService = registerSdkService;
        this.accountCryptographicStateService = accountCryptographicStateService;
        this.sdkService = sdkService;
        this.userDecryptionOptionsService = userDecryptionOptionsService;
        this.convertAccountRequired$ = accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.filter)((account) => account != null), (0,external_rxjs_namespaceObject.switchMap)((account) => (0,external_rxjs_namespaceObject.combineLatest)([
            (0,external_rxjs_namespaceObject.of)(account.id),
            this.organizationService
                .organizations$(account.id)
                .pipe((0,external_rxjs_namespaceObject.filter)((organizations) => organizations != null)),
            this.stateProvider
                .getUserState$(USES_KEY_CONNECTOR, account.id)
                .pipe((0,external_rxjs_namespaceObject.filter)((usesKeyConnector) => usesKeyConnector != null)),
            tokenService.hasAccessToken$(account.id).pipe((0,external_rxjs_namespaceObject.filter)((hasToken) => hasToken)),
        ])), (0,external_rxjs_namespaceObject.switchMap)((_a) => key_connector_service_awaiter(this, [_a], void 0, function* ([userId, organizations, usesKeyConnector]) {
            const loggedInUsingSso = yield this.tokenService.getIsExternal(userId);
            const requiredByOrganization = this.findManagingOrganization(organizations) != null;
            const userIsNotUsingKeyConnector = !usesKeyConnector;
            return loggedInUsingSso && requiredByOrganization && userIsNotUsingKeyConnector;
        })));
    }
    setUsesKeyConnector(usesKeyConnector, userId) {
        return key_connector_service_awaiter(this, void 0, void 0, function* () {
            yield this.stateProvider.getUser(userId, USES_KEY_CONNECTOR).update(() => usesKeyConnector);
        });
    }
    getUsesKeyConnector(userId) {
        return key_connector_service_awaiter(this, void 0, void 0, function* () {
            var _a;
            return ((_a = (yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.stateProvider.getUserState$(USES_KEY_CONNECTOR, userId)))) !== null && _a !== void 0 ? _a : false);
        });
    }
    migrateUser(keyConnectorUrl, userId) {
        return key_connector_service_awaiter(this, void 0, void 0, function* () {
            const sdkKeyConnectorMigration = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.configService.getFeatureFlag$(feature_flag_enum_FeatureFlag.SdkKeyConnectorMigration));
            if (sdkKeyConnectorMigration) {
                try {
                    yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkService.userClient$(userId).pipe((0,external_rxjs_namespaceObject.map)((sdk) => {
                        const env_1 = { stack: [], error: void 0, hasError: false };
                        try {
                            if (!sdk) {
                                throw new Error("SDK not available");
                            }
                            const ref = key_connector_service_addDisposableResource(env_1, sdk.take(), false);
                            return ref.value.user_crypto_management().migrate_to_key_connector(keyConnectorUrl);
                        }
                        catch (e_1) {
                            env_1.error = e_1;
                            env_1.hasError = true;
                        }
                        finally {
                            key_connector_service_disposeResources(env_1);
                        }
                    })));
                }
                catch (e) {
                    this.handleKeyConnectorError(e);
                }
            }
            else {
                const masterKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.masterPasswordService.masterKey$(userId));
                const keyConnectorRequest = new KeyConnectorUserKeyRequest(utils_Utils.fromBufferToB64(masterKey.inner().encryptionKey));
                try {
                    yield this.apiService.postUserKeyToKeyConnector(keyConnectorUrl, keyConnectorRequest);
                }
                catch (e) {
                    this.handleKeyConnectorError(e);
                }
                yield this.apiService.postConvertToKeyConnector();
            }
            yield this.setUsesKeyConnector(true, userId);
            // Clear master password unlock from state
            yield this.masterPasswordService.clearMasterPasswordUnlockData(userId);
            const userDecryptionOptions = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.userDecryptionOptionsService.userDecryptionOptionsById$(userId));
            userDecryptionOptions.hasMasterPassword = false;
            userDecryptionOptions.keyConnectorOption = {
                keyConnectorUrl,
            };
            yield this.userDecryptionOptionsService.setUserDecryptionOptionsById(userId, userDecryptionOptions);
        });
    }
    // TODO: UserKey should be renamed to MasterKey and typed accordingly
    setMasterKeyFromUrl(keyConnectorUrl, userId) {
        return key_connector_service_awaiter(this, void 0, void 0, function* () {
            try {
                const masterKeyResponse = yield this.apiService.getMasterKeyFromKeyConnector(keyConnectorUrl);
                const keyArr = utils_Utils.fromB64ToArray(masterKeyResponse.key);
                const masterKey = new SymmetricCryptoKey(keyArr);
                yield this.masterPasswordService.setMasterKey(masterKey, userId);
            }
            catch (e) {
                this.handleKeyConnectorError(e);
            }
        });
    }
    getManagingOrganization(userId) {
        return key_connector_service_awaiter(this, void 0, void 0, function* () {
            const organizations = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.organizationService.organizations$(userId));
            return this.findManagingOrganization(organizations);
        });
    }
    convertNewSsoUserToKeyConnector(userId) {
        return key_connector_service_awaiter(this, void 0, void 0, function* () {
            const conversion = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.stateProvider.getUserState$(NEW_SSO_USER_KEY_CONNECTOR_CONVERSION, userId));
            if (conversion == null) {
                throw new Error("Key Connector conversion not found");
            }
            const { kdfConfig, keyConnectorUrl, organizationId: ssoOrganizationIdentifier } = conversion;
            if (yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.configService.getFeatureFlag$(feature_flag_enum_FeatureFlag.EnableAccountEncryptionV2KeyConnectorRegistration))) {
                yield this.convertNewSsoUserToKeyConnectorV2(userId, keyConnectorUrl, ssoOrganizationIdentifier);
            }
            else {
                yield this.convertNewSsoUserToKeyConnectorV1(userId, kdfConfig, keyConnectorUrl, ssoOrganizationIdentifier);
            }
            yield this.stateProvider
                .getUser(userId, NEW_SSO_USER_KEY_CONNECTOR_CONVERSION)
                .update(() => null);
        });
    }
    convertNewSsoUserToKeyConnectorV2(userId, keyConnectorUrl, ssoOrganizationIdentifier) {
        return key_connector_service_awaiter(this, void 0, void 0, function* () {
            const result = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.registerSdkService.registerClient$(userId).pipe((0,external_rxjs_namespaceObject.map)((sdk) => {
                const env_2 = { stack: [], error: void 0, hasError: false };
                try {
                    if (!sdk) {
                        throw new Error("SDK not available");
                    }
                    const ref = key_connector_service_addDisposableResource(env_2, sdk.take(), false);
                    return ref.value
                        .auth()
                        .registration()
                        .post_keys_for_key_connector_registration(keyConnectorUrl, ssoOrganizationIdentifier);
                }
                catch (e_2) {
                    env_2.error = e_2;
                    env_2.hasError = true;
                }
                finally {
                    key_connector_service_disposeResources(env_2);
                }
            })));
            if (!("V2" in result.account_cryptographic_state)) {
                const version = Object.keys(result.account_cryptographic_state);
                throw new Error(`Unexpected account cryptographic state version ${version}`);
            }
            yield this.masterPasswordService.setMasterKey(SymmetricCryptoKey.fromString(result.key_connector_key), userId);
            yield this.keyService.setUserKey(SymmetricCryptoKey.fromString(result.user_key), userId);
            yield this.masterPasswordService.setMasterKeyEncryptedUserKey(new enc_string_EncString(result.key_connector_key_wrapped_user_key), userId);
            yield this.accountCryptographicStateService.setAccountCryptographicState(result.account_cryptographic_state, userId);
        });
    }
    convertNewSsoUserToKeyConnectorV1(userId, kdfConfig, keyConnectorUrl, ssoOrganizationIdentifier) {
        return key_connector_service_awaiter(this, void 0, void 0, function* () {
            const password = yield this.keyGenerationService.createKey(512);
            const masterKey = yield this.keyService.makeMasterKey(password.keyB64, yield this.tokenService.getEmail(), kdfConfig);
            const keyConnectorRequest = new KeyConnectorUserKeyRequest(utils_Utils.fromBufferToB64(masterKey.inner().encryptionKey));
            yield this.masterPasswordService.setMasterKey(masterKey, userId);
            const userKey = yield this.keyService.makeUserKey(masterKey);
            yield this.keyService.setUserKey(userKey[0], userId);
            yield this.masterPasswordService.setMasterKeyEncryptedUserKey(userKey[1], userId);
            const [pubKey, privKey] = yield this.keyService.makeKeyPair(userKey[0]);
            try {
                yield this.apiService.postUserKeyToKeyConnector(keyConnectorUrl, keyConnectorRequest);
            }
            catch (e) {
                this.handleKeyConnectorError(e);
            }
            const keys = new KeysRequest(pubKey, privKey.encryptedString);
            const setPasswordRequest = new SetKeyConnectorKeyRequest(userKey[1].encryptedString, kdfConfig, ssoOrganizationIdentifier, keys);
            yield this.apiService.postSetKeyConnectorKey(setPasswordRequest);
        });
    }
    setNewSsoUserKeyConnectorConversionData(conversion, userId) {
        return key_connector_service_awaiter(this, void 0, void 0, function* () {
            yield this.stateProvider
                .getUser(userId, NEW_SSO_USER_KEY_CONNECTOR_CONVERSION)
                .update(() => conversion);
        });
    }
    requiresDomainConfirmation$(userId) {
        return this.stateProvider.getUserState$(NEW_SSO_USER_KEY_CONNECTOR_CONVERSION, userId).pipe((0,external_rxjs_namespaceObject.map)((data) => data != null
            ? {
                keyConnectorUrl: data.keyConnectorUrl,
                organizationSsoIdentifier: data.organizationId,
            }
            : null));
    }
    handleKeyConnectorError(e) {
        this.logService.error(e);
        if (this.logoutCallback != null) {
            // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
            // eslint-disable-next-line @typescript-eslint/no-floating-promises
            this.logoutCallback("keyConnectorError");
        }
        throw new Error("Key Connector error");
    }
    findManagingOrganization(organizations) {
        return organizations.find((o) => o.keyConnectorEnabled &&
            o.type !== organization_user_type_enum_OrganizationUserType.Admin &&
            o.type !== organization_user_type_enum_OrganizationUserType.Owner &&
            !o.isProviderUser);
    }
}

;// ../../libs/common/src/key-management/master-password/services/default-master-password-unlock.service.ts
var default_master_password_unlock_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};


class DefaultMasterPasswordUnlockService {
    constructor(masterPasswordService, keyService, logService) {
        this.masterPasswordService = masterPasswordService;
        this.keyService = keyService;
        this.logService = logService;
    }
    unlockWithMasterPassword(masterPassword, userId) {
        return default_master_password_unlock_service_awaiter(this, void 0, void 0, function* () {
            this.validateInput(masterPassword, userId);
            const masterPasswordUnlockData = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.masterPasswordService.masterPasswordUnlockData$(userId));
            if (masterPasswordUnlockData == null) {
                throw new Error("Master password unlock data was not found for the user " + userId);
            }
            const userKey = yield this.masterPasswordService.unwrapUserKeyFromMasterPasswordUnlockData(masterPassword, masterPasswordUnlockData);
            yield this.setLegacyState(masterPassword, masterPasswordUnlockData, userId);
            return userKey;
        });
    }
    proofOfDecryption(masterPassword, userId) {
        return default_master_password_unlock_service_awaiter(this, void 0, void 0, function* () {
            this.validateInput(masterPassword, userId);
            try {
                const masterPasswordUnlockData = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.masterPasswordService.masterPasswordUnlockData$(userId));
                if (masterPasswordUnlockData == null) {
                    this.logService.warning(`[DefaultMasterPasswordUnlockService] No master password unlock data found for user ${userId} returning false.`);
                    return false;
                }
                const userKey = yield this.masterPasswordService.unwrapUserKeyFromMasterPasswordUnlockData(masterPassword, masterPasswordUnlockData);
                return userKey != null;
            }
            catch (error) {
                // masterPasswordService.unwrapUserKeyFromMasterPasswordUnlockData is expected to throw if the password is incorrect.
                // Currently this throws CryptoError:InvalidKey if decrypting the user key fails at all.
                if ((0,bitwarden_wasm_internal_bg/* isCryptoError */.gkX)(error) && error.variant === "InvalidKey") {
                    this.logService.debug(`[DefaultMasterPasswordUnlockService] Error during proof of decryption for user ${userId} returning false: ${error}`);
                }
                else {
                    this.logService.error(`[DefaultMasterPasswordUnlockService] Unexpected error during proof of decryption for user ${userId} returning false: ${error}`);
                }
                return false;
            }
        });
    }
    validateInput(masterPassword, userId) {
        if (masterPassword == null || masterPassword === "") {
            throw new Error("Master password is required");
        }
        if (userId == null) {
            throw new Error("User ID is required");
        }
    }
    // Previously unlocking had the side effect of setting the masterKey and masterPasswordHash in state.
    // This is to preserve that behavior, once masterKey and masterPasswordHash state is removed this should be removed as well.
    setLegacyState(masterPassword, masterPasswordUnlockData, userId) {
        return default_master_password_unlock_service_awaiter(this, void 0, void 0, function* () {
            const masterKey = yield this.keyService.makeMasterKey(masterPassword, masterPasswordUnlockData.salt, masterPasswordUnlockData.kdf);
            if (!masterKey) {
                throw new Error("Master key could not be created to set legacy master password state.");
            }
            yield this.masterPasswordService.setMasterKey(masterKey, userId);
        });
    }
}

;// external "semver"
const external_semver_namespaceObject = require("semver");
;// ../../libs/common/src/enums/push-technology.enum.ts
/**
 * The preferred push technology of the server.
 */
// FIXME: update to use a const object instead of a typescript enum
// eslint-disable-next-line @bitwarden/platform/no-enums
var PushTechnology;
(function (PushTechnology) {
    /**
     * Indicates that we should use SignalR over web sockets to receive push server notifications from the server.
     */
    PushTechnology[PushTechnology["SignalR"] = 0] = "SignalR";
    /**
     * Indicates that we should use WebPush to receive push server notifications from the server.
     */
    PushTechnology[PushTechnology["WebPush"] = 1] = "WebPush";
})(PushTechnology || (PushTechnology = {}));

;// ../../libs/common/src/platform/abstractions/config/server-config.ts

const dayInMilliseconds = 24 * 3600 * 1000;
class ServerConfig {
    constructor(serverConfigData) {
        var _a, _b;
        this.featureStates = {};
        this.version = serverConfigData.version;
        this.gitHash = serverConfigData.gitHash;
        this.server = serverConfigData.server;
        this.utcDate = new Date(serverConfigData.utcDate);
        this.environment = serverConfigData.environment;
        this.featureStates = serverConfigData.featureStates;
        this.push =
            serverConfigData.push == null
                ? {
                    pushTechnology: PushTechnology.SignalR,
                }
                : {
                    pushTechnology: serverConfigData.push.pushTechnology,
                    vapidPublicKey: serverConfigData.push.vapidPublicKey,
                };
        this.settings = serverConfigData.settings;
        if (((_a = this.server) === null || _a === void 0 ? void 0 : _a.name) == null && ((_b = this.server) === null || _b === void 0 ? void 0 : _b.url) == null) {
            this.server = null;
        }
    }
    getAgeInMilliseconds() {
        var _a;
        return new Date().getTime() - ((_a = this.utcDate) === null || _a === void 0 ? void 0 : _a.getTime());
    }
    isValid() {
        return this.getAgeInMilliseconds() <= dayInMilliseconds;
    }
    static fromJSON(obj) {
        if (obj == null) {
            return null;
        }
        return new ServerConfig(obj);
    }
}

;// ../../libs/common/src/platform/misc/flags.ts
function getFlags(envFlags) {
    if (typeof envFlags === "string") {
        return JSON.parse(envFlags);
    }
    else {
        return envFlags;
    }
}
/**
 * Gets the value of a feature flag from environment.
 * All flags default to "on" (true).
 * Only use for shared code in `libs`, otherwise use the client-specific function.
 * @param flag The name of the feature flag to check
 * @returns The value of the flag
 */
function flagEnabled(flag) {
    var _a;
    const flags = (_a = getFlags({"sdk":true})) !== null && _a !== void 0 ? _a : {};
    return flags[flag] == null || !!flags[flag];
}
/**
 * Gets the value of a dev flag from environment.
 * Will always return false unless in development.
 * Only use for shared code in `libs`, otherwise use the client-specific function.
 * @param flag The name of the dev flag to check
 * @returns The value of the flag
 */
function devFlagEnabled(flag) {
    if (true) {
        return false;
    }
    // removed by dead control flow

    // removed by dead control flow

}
/**
 * Gets the value of a dev flag from environment.
 * Will always return false unless in development.
 * @param flag The name of the dev flag to check
 * @returns The value of the flag
 * @throws Error if the flag is not enabled
 */
function devFlagValue(flag) {
    if (!devFlagEnabled(flag)) {
        throw new Error(`This method should not be called, it is protected by a disabled dev flag.`);
    }
    const devFlags = getFlags({});
    return devFlags[flag];
}

;// ../../libs/common/src/platform/models/domain/server-settings.ts
class ServerSettings {
    constructor(data) {
        var _a;
        this.disableUserRegistration = (_a = data === null || data === void 0 ? void 0 : data.disableUserRegistration) !== null && _a !== void 0 ? _a : false;
    }
}

;// ../../libs/common/src/platform/models/data/server-config.data.ts

class ServerConfigData {
    constructor(serverConfigResponse) {
        this.featureStates = {};
        this.version = serverConfigResponse === null || serverConfigResponse === void 0 ? void 0 : serverConfigResponse.version;
        this.gitHash = serverConfigResponse === null || serverConfigResponse === void 0 ? void 0 : serverConfigResponse.gitHash;
        this.server = (serverConfigResponse === null || serverConfigResponse === void 0 ? void 0 : serverConfigResponse.server)
            ? new ThirdPartyServerConfigData(serverConfigResponse.server)
            : null;
        this.utcDate = new Date().toISOString();
        this.environment = (serverConfigResponse === null || serverConfigResponse === void 0 ? void 0 : serverConfigResponse.environment)
            ? new EnvironmentServerConfigData(serverConfigResponse.environment)
            : null;
        this.featureStates = serverConfigResponse === null || serverConfigResponse === void 0 ? void 0 : serverConfigResponse.featureStates;
        this.settings = new ServerSettings(serverConfigResponse.settings);
        this.push = (serverConfigResponse === null || serverConfigResponse === void 0 ? void 0 : serverConfigResponse.push)
            ? new PushSettingsConfigData(serverConfigResponse.push)
            : null;
    }
    static fromJSON(obj) {
        return Object.assign(new ServerConfigData({}), obj, {
            server: (obj === null || obj === void 0 ? void 0 : obj.server) ? ThirdPartyServerConfigData.fromJSON(obj.server) : null,
            environment: (obj === null || obj === void 0 ? void 0 : obj.environment) ? EnvironmentServerConfigData.fromJSON(obj.environment) : null,
        });
    }
}
class PushSettingsConfigData {
    constructor(response) {
        this.pushTechnology = response.pushTechnology;
        this.vapidPublicKey = response.vapidPublicKey;
    }
    static fromJSON(obj) {
        return Object.assign(new PushSettingsConfigData({}), obj);
    }
}
class ThirdPartyServerConfigData {
    constructor(response) {
        this.name = response.name;
        this.url = response.url;
    }
    static fromJSON(obj) {
        return Object.assign(new ThirdPartyServerConfigData({}), obj);
    }
}
class EnvironmentServerConfigData {
    constructor(response) {
        this.cloudRegion = response.cloudRegion;
        this.vault = response.vault;
        this.api = response.api;
        this.identity = response.identity;
        this.notifications = response.notifications;
        this.sso = response.sso;
        this.fillAssistRules = response.fillAssistRules;
    }
    static fromJSON(obj) {
        return Object.assign(new EnvironmentServerConfigData({}), obj);
    }
}

;// ../../libs/common/src/platform/services/config/default-config.service.ts
var default_config_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};










const RETRIEVAL_INTERVAL = devFlagEnabled("configRetrievalIntervalMs")
    ? devFlagValue("configRetrievalIntervalMs")
    : 3600000; // 1 hour
const SLOW_EMISSION_GUARD = 800;
const default_config_service_USER_SERVER_CONFIG = new UserKeyDefinition(CONFIG_DISK, "serverConfig", {
    deserializer: (data) => (data == null ? null : ServerConfig.fromJSON(data)),
    clearOn: ["logout"],
});
const GLOBAL_SERVER_CONFIGURATIONS = KeyDefinition.record(CONFIG_DISK, "byServer", {
    deserializer: (data) => (data == null ? null : ServerConfig.fromJSON(data)),
});
const environmentComparer = (previous, current) => {
    return previous.getApiUrl() === current.getApiUrl();
};
// FIXME: currently we are limited to api requests for active users. Update to accept a UserId and APIUrl once ApiService supports it.
class DefaultConfigService {
    constructor(configApiService, environmentService, logService, stateProvider, authService) {
        this.configApiService = configApiService;
        this.environmentService = environmentService;
        this.logService = logService;
        this.stateProvider = stateProvider;
        this.authService = authService;
        this.failedFetchFallbackSubject = new external_rxjs_namespaceObject.Subject();
        this.serverCommunicationConfigSubject = new external_rxjs_namespaceObject.ReplaySubject(1);
        this.serverCommunicationConfig$ = this.serverCommunicationConfigSubject.asObservable();
        const globalConfig$ = this.environmentService.globalEnvironment$.pipe((0,external_rxjs_namespaceObject.distinctUntilChanged)(environmentComparer), (0,external_rxjs_namespaceObject.switchMap)((environment) => this.globalConfigFor$(environment.getApiUrl()).pipe((0,external_rxjs_namespaceObject.map)((config) => {
            return [config, null, environment, config];
        }))));
        this.serverConfig$ = this.stateProvider.activeUserId$.pipe((0,external_rxjs_namespaceObject.distinctUntilChanged)(), (0,external_rxjs_namespaceObject.switchMap)((userId) => {
            if (userId == null) {
                // Global
                return globalConfig$;
            }
            return this.authService.authStatusFor$(userId).pipe((0,external_rxjs_namespaceObject.map)((authStatus) => authStatus === authentication_status_AuthenticationStatus.Unlocked), (0,external_rxjs_namespaceObject.distinctUntilChanged)(), (0,external_rxjs_namespaceObject.switchMap)((isUnlocked) => {
                if (!isUnlocked) {
                    return globalConfig$;
                }
                return (0,external_rxjs_namespaceObject.combineLatest)([
                    this.environmentService
                        .getEnvironment$(userId)
                        .pipe((0,external_rxjs_namespaceObject.distinctUntilChanged)(environmentComparer)),
                    this.userConfigFor$(userId),
                ]).pipe((0,external_rxjs_namespaceObject.switchMap)(([environment, config]) => {
                    if (config == null) {
                        // If the user doesn't have any config yet, use the global config for that url as the fallback
                        return this.globalConfigFor$(environment.getApiUrl()).pipe((0,external_rxjs_namespaceObject.map)((globalConfig) => [null, userId, environment, globalConfig]));
                    }
                    return (0,external_rxjs_namespaceObject.of)([config, userId, environment, config]);
                }));
            }));
        }), (0,external_rxjs_namespaceObject.tap)((rec) => default_config_service_awaiter(this, void 0, void 0, function* () {
            const [existingConfig, userId, environment, fallbackConfig] = rec;
            // Grab new config if older retrieval interval
            if (!existingConfig || this.olderThanRetrievalInterval(existingConfig.utcDate)) {
                yield this.renewConfig(existingConfig, userId, environment, fallbackConfig);
            }
        })), (0,external_rxjs_namespaceObject.switchMap)(([existingConfig]) => {
            // If we needed to fetch, stop this emit, we'll get a new one after update
            // This is split up with the above tap because we need to return an observable from a failed promise,
            // which isn't very doable since promises are converted to observables in switchMap
            if (!existingConfig || this.olderThanRetrievalInterval(existingConfig.utcDate)) {
                return external_rxjs_namespaceObject.NEVER;
            }
            return (0,external_rxjs_namespaceObject.of)(existingConfig);
        }), 
        // If fetch fails, we'll emit on this subject to fallback to the existing config
        (0,external_rxjs_namespaceObject.mergeWith)(this.failedFetchFallbackSubject), (0,external_rxjs_namespaceObject.share)({ connector: () => new external_rxjs_namespaceObject.ReplaySubject(1), resetOnRefCountZero: () => (0,external_rxjs_namespaceObject.timer)(1000) }));
        this.cloudRegion$ = this.serverConfig$.pipe((0,external_rxjs_namespaceObject.map)((config) => { var _a, _b; return (_b = (_a = config === null || config === void 0 ? void 0 : config.environment) === null || _a === void 0 ? void 0 : _a.cloudRegion) !== null && _b !== void 0 ? _b : Region.US; }));
        this.serverSettings$ = this.serverConfig$.pipe((0,external_rxjs_namespaceObject.map)((config) => { var _a; return (_a = config === null || config === void 0 ? void 0 : config.settings) !== null && _a !== void 0 ? _a : new ServerSettings(); }));
    }
    getFeatureFlag$(key) {
        return this.serverConfig$.pipe((0,external_rxjs_namespaceObject.map)((serverConfig) => getFeatureFlagValue(serverConfig, key)));
    }
    userCachedFeatureFlag$(key, userId) {
        return this.stateProvider
            .getUser(userId, default_config_service_USER_SERVER_CONFIG)
            .state$.pipe((0,external_rxjs_namespaceObject.map)((config) => getFeatureFlagValue(config, key)));
    }
    getFeatureFlag(key) {
        return default_config_service_awaiter(this, void 0, void 0, function* () {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.getFeatureFlag$(key));
        });
    }
    checkServerMeetsVersionRequirement$(minimumRequiredServerVersion) {
        return this.serverConfig$.pipe((0,external_rxjs_namespaceObject.map)((serverConfig) => {
            if (serverConfig == null) {
                return false;
            }
            const serverVersion = new external_semver_namespaceObject.SemVer(serverConfig.version);
            return serverVersion.compare(minimumRequiredServerVersion) >= 0;
        }));
    }
    ensureConfigFetched() {
        return default_config_service_awaiter(this, void 0, void 0, function* () {
            // Triggering a retrieval for the given user ensures that the config is less than RETRIEVAL_INTERVAL old
            yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.serverConfig$);
        });
    }
    olderThanRetrievalInterval(date) {
        return new Date().getTime() - date.getTime() > RETRIEVAL_INTERVAL;
    }
    // Updates the on-disk configuration with a newly retrieved configuration
    renewConfig(existingConfig, userId, environment, fallbackConfig) {
        return default_config_service_awaiter(this, void 0, void 0, function* () {
            var _a, _b, _c;
            try {
                // Feature flags often have a big impact on user experience, lets ensure we return some value
                // somewhat quickly even though it may not be accurate, we won't cancel the HTTP request
                // though so that hopefully it can have finished and hydrated a more accurate value.
                const handle = setTimeout(() => {
                    this.logService.info("Environment did not respond in time, emitting previous config.");
                    this.failedFetchFallbackSubject.next(fallbackConfig);
                }, SLOW_EMISSION_GUARD);
                const response = yield this.configApiService.get(userId);
                clearTimeout(handle);
                const newConfig = new ServerConfig(new ServerConfigData(response));
                this.parseBoostrapConfig(response);
                // Update the environment region
                if (((_a = newConfig === null || newConfig === void 0 ? void 0 : newConfig.environment) === null || _a === void 0 ? void 0 : _a.cloudRegion) != null &&
                    ((_b = existingConfig === null || existingConfig === void 0 ? void 0 : existingConfig.environment) === null || _b === void 0 ? void 0 : _b.cloudRegion) != newConfig.environment.cloudRegion) {
                    // Null userId sets global, otherwise sets to the given user
                    yield this.environmentService.setCloudRegion(userId, (_c = newConfig === null || newConfig === void 0 ? void 0 : newConfig.environment) === null || _c === void 0 ? void 0 : _c.cloudRegion);
                }
                if (userId == null) {
                    // update global state with new pulled config
                    yield this.stateProvider.getGlobal(GLOBAL_SERVER_CONFIGURATIONS).update((configs) => {
                        return Object.assign(Object.assign({}, configs), { [environment.getApiUrl()]: newConfig });
                    });
                }
                else {
                    // update state with new pulled config
                    yield this.stateProvider.setUserState(default_config_service_USER_SERVER_CONFIG, newConfig, userId);
                }
            }
            catch (e) {
                // mutate error to be handled by catchError
                this.logService.error(`Unable to fetch ServerConfig from ${environment.getApiUrl()}`, e);
                // Emit the existing config
                this.failedFetchFallbackSubject.next(fallbackConfig);
            }
        });
    }
    globalConfigFor$(apiUrl) {
        return this.stateProvider
            .getGlobal(GLOBAL_SERVER_CONFIGURATIONS)
            .state$.pipe((0,external_rxjs_namespaceObject.map)((configs) => { var _a; return (_a = configs === null || configs === void 0 ? void 0 : configs[apiUrl]) !== null && _a !== void 0 ? _a : null; }));
    }
    userConfigFor$(userId) {
        return this.stateProvider.getUser(userId, default_config_service_USER_SERVER_CONFIG).state$;
    }
    parseBoostrapConfig(response) {
        var _a, _b, _c;
        const bootstrap = (_b = (_a = response.communication) === null || _a === void 0 ? void 0 : _a.bootstrap) !== null && _b !== void 0 ? _b : null;
        const vaultUrl = (_c = response.environment) === null || _c === void 0 ? void 0 : _c.vault;
        // Emit communication config so subscribers (e.g. ServerCommunicationConfigService) can persist it
        const communicationConfig = (bootstrap === null || bootstrap === void 0 ? void 0 : bootstrap.type) === "ssoCookieVendor" && vaultUrl != null
            ? {
                bootstrap: {
                    type: "ssoCookieVendor",
                    idpLoginUrl: bootstrap.idpLoginUrl,
                    cookieName: bootstrap.cookieName,
                    cookieDomain: bootstrap.cookieDomain,
                    vaultUrl: vaultUrl,
                    cookieValue: undefined,
                },
            }
            : { bootstrap: { type: "direct" } };
        this.serverCommunicationConfigSubject.next(communicationConfig);
    }
}

;// ../../libs/common/src/key-management/master-password/services/master-password.service.ts
var master_password_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore













/** Memory since master key shouldn't be available on lock */
const MASTER_KEY = new UserKeyDefinition(MASTER_PASSWORD_MEMORY, "masterKey", {
    deserializer: (masterKey) => SymmetricCryptoKey.fromJSON(masterKey),
    clearOn: ["lock", "logout"],
});
/** Disk to persist through lock */
const master_password_service_MASTER_KEY_ENCRYPTED_USER_KEY = new UserKeyDefinition(MASTER_PASSWORD_DISK, "masterKeyEncryptedUserKey", {
    deserializer: (key) => key,
    clearOn: ["logout"],
});
/** Disk to persist through lock and account switches */
const FORCE_SET_PASSWORD_REASON = new UserKeyDefinition(MASTER_PASSWORD_DISK, "forceSetPasswordReason", {
    deserializer: (reason) => reason,
    clearOn: ["logout"],
});
/** Disk to persist through lock */
const master_password_service_MASTER_PASSWORD_UNLOCK_KEY = new UserKeyDefinition(MASTER_PASSWORD_UNLOCK_DISK, "masterPasswordUnlockKey", {
    deserializer: (obj) => MasterPasswordUnlockData.fromJSON(obj),
    clearOn: ["logout"],
});
class MasterPasswordService {
    constructor(stateProvider, keyGenerationService, logService, cryptoFunctionService, accountService) {
        this.stateProvider = stateProvider;
        this.keyGenerationService = keyGenerationService;
        this.logService = logService;
        this.cryptoFunctionService = cryptoFunctionService;
        this.accountService = accountService;
    }
    userHasMasterPassword(userId) {
        return master_password_service_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(userId, "userId");
            // A user has a master-password if they have a master-key encrypted user key *but* are not a key connector user
            // Note: We can't use the key connector service as an abstraction here because it causes a run-time dependency injection cycle between KC service and MP service.
            const usesKeyConnector = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.stateProvider.getUser(userId, USES_KEY_CONNECTOR).state$);
            const usesMasterKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.stateProvider.getUser(userId, master_password_service_MASTER_KEY_ENCRYPTED_USER_KEY).state$);
            return usesMasterKey && !usesKeyConnector;
        });
    }
    saltForUser$(userId) {
        assertNonNullish(userId, "userId");
        // Note: We can't use the config service as an abstraction here because it creates a circular dependency: ConfigService -> ConfigApiService -> ApiService -> VaultTimeoutSettingsService -> KeyService -> MP service.
        return this.stateProvider.getUser(userId, default_config_service_USER_SERVER_CONFIG).state$.pipe((0,external_rxjs_namespaceObject.map)((serverConfig) => getFeatureFlagValue(serverConfig, feature_flag_enum_FeatureFlag.PM31088_MasterPasswordServiceEmitSalt)), (0,external_rxjs_namespaceObject.switchMap)((enabled) => (0,external_rxjs_namespaceObject.iif)(() => enabled, this.masterPasswordUnlockData$(userId).pipe((0,external_rxjs_namespaceObject.switchMap)((unlockData) => {
            if (unlockData != null) {
                return (0,external_rxjs_namespaceObject.of)(unlockData.salt);
            }
            // No unlock data. Determine whether this is a hydration failure
            // or a user who legitimately has no master password yet
            // (e.g., TDE offboarding).
            return (0,external_rxjs_namespaceObject.from)(this.userHasMasterPassword(userId)).pipe((0,external_rxjs_namespaceObject.switchMap)((hasMp) => {
                if (hasMp) {
                    throw new Error("Master password unlock data not found for user.");
                }
                // TODO: PM-32059 — Edge case: user does not have a master password (e.g., TDE offboarding).
                // When salt is disconnected from email (Stage 3), part of that should involve a "generateSalt"
                // function that TDE offboarding deliberately calls; it should not be a side-effect of retrieving
                // the user's salt.
                return this.accountService.accounts$.pipe((0,external_rxjs_namespaceObject.map)((accounts) => accounts[userId].email), (0,external_rxjs_namespaceObject.map)((email) => this.emailToSalt(email)));
            }));
        })), this.accountService.accounts$.pipe((0,external_rxjs_namespaceObject.map)((accounts) => accounts[userId].email), (0,external_rxjs_namespaceObject.map)((email) => this.emailToSalt(email))))));
    }
    masterKey$(userId) {
        if (userId == null) {
            throw new Error("User ID is required.");
        }
        return this.stateProvider.getUser(userId, MASTER_KEY).state$;
    }
    forceSetPasswordReason$(userId) {
        if (userId == null) {
            throw new Error("User ID is required.");
        }
        return this.stateProvider
            .getUser(userId, FORCE_SET_PASSWORD_REASON)
            .state$.pipe((0,external_rxjs_namespaceObject.map)((reason) => reason !== null && reason !== void 0 ? reason : ForceSetPasswordReason.None));
    }
    // TODO: Remove this method and decrypt directly in the service instead
    getMasterKeyEncryptedUserKey(userId) {
        return master_password_service_awaiter(this, void 0, void 0, function* () {
            if (userId == null) {
                throw new Error("User ID is required.");
            }
            const key = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.stateProvider.getUser(userId, master_password_service_MASTER_KEY_ENCRYPTED_USER_KEY).state$);
            return enc_string_EncString.fromJSON(key);
        });
    }
    emailToSalt(email) {
        return email.toLowerCase().trim();
    }
    setMasterKey(masterKey, userId) {
        return master_password_service_awaiter(this, void 0, void 0, function* () {
            if (masterKey == null) {
                throw new Error("Master key is required.");
            }
            if (userId == null) {
                throw new Error("User ID is required.");
            }
            yield this.stateProvider.getUser(userId, MASTER_KEY).update((_) => masterKey);
        });
    }
    clearMasterKey(userId) {
        return master_password_service_awaiter(this, void 0, void 0, function* () {
            if (userId == null) {
                throw new Error("User ID is required.");
            }
            yield this.stateProvider.getUser(userId, MASTER_KEY).update((_) => null);
        });
    }
    setMasterKeyEncryptedUserKey(encryptedKey, userId) {
        return master_password_service_awaiter(this, void 0, void 0, function* () {
            if (encryptedKey == null || encryptedKey.encryptedString == null) {
                throw new Error("Encrypted Key is required.");
            }
            if (userId == null) {
                throw new Error("User ID is required.");
            }
            yield this.stateProvider
                .getUser(userId, master_password_service_MASTER_KEY_ENCRYPTED_USER_KEY)
                .update((_) => encryptedKey.toJSON());
        });
    }
    setForceSetPasswordReason(reason, userId) {
        return master_password_service_awaiter(this, void 0, void 0, function* () {
            if (reason == null) {
                throw new Error("Reason is required.");
            }
            if (userId == null) {
                throw new Error("User ID is required.");
            }
            // Don't overwrite AdminForcePasswordReset with any other reasons other than None
            // as we must allow a reset when the user has completed admin account recovery
            const currentReason = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.forceSetPasswordReason$(userId));
            if (currentReason === ForceSetPasswordReason.AdminForcePasswordReset &&
                reason !== ForceSetPasswordReason.None) {
                return;
            }
            yield this.stateProvider.getUser(userId, FORCE_SET_PASSWORD_REASON).update((_) => reason);
        });
    }
    decryptUserKeyWithMasterKey(masterKey, userId, userKey) {
        return master_password_service_awaiter(this, void 0, void 0, function* () {
            userKey !== null && userKey !== void 0 ? userKey : (userKey = yield this.getMasterKeyEncryptedUserKey(userId));
            masterKey !== null && masterKey !== void 0 ? masterKey : (masterKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.masterKey$(userId)));
            if (masterKey == null) {
                throw new Error("No master key found.");
            }
            yield SdkLoadService.Ready;
            try {
                return new SymmetricCryptoKey(bitwarden_wasm_internal_bg/* PureCrypto */.IEs.decrypt_user_key_with_master_key(userKey.toSdk(), masterKey.toEncoded()));
            }
            catch (_a) {
                this.logService.warning("Failed to decrypt user key with master key.");
                return null;
            }
        });
    }
    makeMasterPasswordAuthenticationData(password, kdf, salt) {
        return master_password_service_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(password, "password");
            assertNonNullish(kdf, "kdf");
            assertNonNullish(salt, "salt");
            if (password === "") {
                throw new Error("Master password cannot be empty.");
            }
            // We don't trust callers to use masterpasswordsalt correctly. They may type assert incorrectly.
            salt = salt.toLowerCase().trim();
            const SERVER_AUTHENTICATION_HASH_ITERATIONS = 1;
            const masterKey = (yield this.keyGenerationService.deriveKeyFromPassword(password, salt, kdf));
            const masterPasswordAuthenticationHash = utils_Utils.fromBufferToB64(yield this.cryptoFunctionService.pbkdf2(masterKey.toEncoded(), password, "sha256", SERVER_AUTHENTICATION_HASH_ITERATIONS));
            return {
                salt,
                kdf,
                masterPasswordAuthenticationHash,
            };
        });
    }
    makeMasterPasswordUnlockData(password, kdf, salt, userKey) {
        return master_password_service_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(password, "password");
            assertNonNullish(kdf, "kdf");
            assertNonNullish(salt, "salt");
            assertNonNullish(userKey, "userKey");
            if (password === "") {
                throw new Error("Master password cannot be empty.");
            }
            // We don't trust callers to use masterpasswordsalt correctly. They may type assert incorrectly.
            salt = salt.toLowerCase().trim();
            yield SdkLoadService.Ready;
            const masterKeyWrappedUserKey = bitwarden_wasm_internal_bg/* PureCrypto */.IEs.encrypt_user_key_with_master_password(userKey.toEncoded(), password, salt, kdf.toSdkConfig());
            return new MasterPasswordUnlockData(salt, kdf, masterKeyWrappedUserKey);
        });
    }
    unwrapUserKeyFromMasterPasswordUnlockData(password, masterPasswordUnlockData) {
        return master_password_service_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(password, "password");
            assertNonNullish(masterPasswordUnlockData, "masterPasswordUnlockData");
            yield SdkLoadService.Ready;
            const userKey = new SymmetricCryptoKey(bitwarden_wasm_internal_bg/* PureCrypto */.IEs.decrypt_user_key_with_master_password(masterPasswordUnlockData.masterKeyWrappedUserKey, password, masterPasswordUnlockData.salt, masterPasswordUnlockData.kdf.toSdkConfig()));
            return userKey;
        });
    }
    setMasterPasswordUnlockData(masterPasswordUnlockData, userId) {
        return master_password_service_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(masterPasswordUnlockData, "masterPasswordUnlockData");
            assertNonNullish(userId, "userId");
            yield this.stateProvider
                .getUser(userId, master_password_service_MASTER_PASSWORD_UNLOCK_KEY)
                .update(() => masterPasswordUnlockData.toJSON());
        });
    }
    clearMasterPasswordUnlockData(userId) {
        return master_password_service_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(userId, "userId");
            yield this.stateProvider.getUser(userId, master_password_service_MASTER_PASSWORD_UNLOCK_KEY).update(() => null);
        });
    }
    masterPasswordUnlockData$(userId) {
        assertNonNullish(userId, "userId");
        return this.stateProvider.getUser(userId, master_password_service_MASTER_PASSWORD_UNLOCK_KEY).state$;
    }
    setLegacyMasterKeyFromUnlockData(password, masterPasswordUnlockData, userId) {
        return master_password_service_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(password, "password");
            assertNonNullish(masterPasswordUnlockData, "masterPasswordUnlockData");
            assertNonNullish(userId, "userId");
            const masterKey = (yield this.keyGenerationService.deriveKeyFromPassword(password, masterPasswordUnlockData.salt, masterPasswordUnlockData.kdf));
            yield this.setMasterKey(masterKey, userId);
        });
    }
}

;// ../../libs/common/src/key-management/pin/pin.state.ts

/**
 * The persistent (stored on disk) version of the UserKey, stored in a `PasswordProtectedKeyEnvelope`.
 *
 * @remarks Persists through a client reset. Used when `requireMasterPasswordOnClientRestart` is disabled.
 * @see SetPinComponent.setPinForm.requireMasterPasswordOnClientRestart
 */
const PIN_PROTECTED_USER_KEY_ENVELOPE_PERSISTENT = new UserKeyDefinition(PIN_DISK, "pinProtectedUserKeyEnvelopePersistent", {
    deserializer: (jsonValue) => jsonValue,
    clearOn: ["logout"],
});
/**
 * The ephemeral (stored in memory) version of the UserKey, stored in a `PasswordProtectedKeyEnvelope`.
 */
const PIN_PROTECTED_USER_KEY_ENVELOPE_EPHEMERAL = UserKeyDefinition.record(PIN_MEMORY, "pinProtectedUserKeyEnvelopeEphemeral", {
    deserializer: (jsonValue) => jsonValue,
    clearOn: ["logout"],
    // Prevents the state from caching and rxjs observable becoming hot observable.
    cleanupDelayMs: 0,
});
/**
 * The PIN, encrypted by the UserKey.
 */
const pin_state_USER_KEY_ENCRYPTED_PIN = new UserKeyDefinition(PIN_DISK, "userKeyEncryptedPin", {
    deserializer: (jsonValue) => jsonValue,
    clearOn: ["logout"],
});

;// ../../libs/common/src/key-management/pin/pin-state.service.implementation.ts
var pin_state_service_implementation_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};




const EPHEMERAL_PIN_ENVELOPE_KEY = "";
class PinStateService {
    constructor(stateProvider) {
        this.stateProvider = stateProvider;
    }
    userKeyEncryptedPin$(userId) {
        assertNonNullish(userId, "userId");
        return this.stateProvider
            .getUserState$(pin_state_USER_KEY_ENCRYPTED_PIN, userId)
            .pipe((0,external_rxjs_namespaceObject.map)((value) => (value ? new enc_string_EncString(value) : null)));
    }
    pinSet$(userId) {
        assertNonNullish(userId, "userId");
        return this.pinLockType$(userId).pipe((0,external_rxjs_namespaceObject.map)((pinLockType) => pinLockType !== "DISABLED"));
    }
    pinLockType$(userId) {
        assertNonNullish(userId, "userId");
        return (0,external_rxjs_namespaceObject.combineLatest)([
            this.pinProtectedUserKeyEnvelope$(userId, "PERSISTENT").pipe((0,external_rxjs_namespaceObject.map)((key) => key != null)),
            this.stateProvider
                .getUserState$(pin_state_USER_KEY_ENCRYPTED_PIN, userId)
                .pipe((0,external_rxjs_namespaceObject.map)((key) => key != null)),
        ]).pipe((0,external_rxjs_namespaceObject.map)(([isPersistentPinSet, isPinSet]) => {
            if (isPersistentPinSet) {
                return "PERSISTENT";
            }
            else if (isPinSet) {
                return "EPHEMERAL";
            }
            else {
                return "DISABLED";
            }
        }));
    }
    getPinLockType(userId) {
        return pin_state_service_implementation_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(userId, "userId");
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.pinLockType$(userId));
        });
    }
    getPinProtectedUserKeyEnvelope(userId, pinLockType) {
        return pin_state_service_implementation_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(userId, "userId");
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.pinProtectedUserKeyEnvelope$(userId, pinLockType));
        });
    }
    setPinState(userId, pinProtectedUserKeyEnvelope, userKeyEncryptedPin, pinLockType) {
        return pin_state_service_implementation_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(userId, "userId");
            assertNonNullish(pinProtectedUserKeyEnvelope, "pinProtectedUserKeyEnvelope");
            assertNonNullish(pinLockType, "pinLockType");
            if (pinLockType === "EPHEMERAL") {
                yield this.stateProvider.setUserState(PIN_PROTECTED_USER_KEY_ENVELOPE_EPHEMERAL, { [EPHEMERAL_PIN_ENVELOPE_KEY]: { pin_envelope: pinProtectedUserKeyEnvelope } }, userId);
            }
            else if (pinLockType === "PERSISTENT") {
                yield this.stateProvider.setUserState(PIN_PROTECTED_USER_KEY_ENVELOPE_PERSISTENT, pinProtectedUserKeyEnvelope, userId);
            }
            else {
                throw new Error(`Cannot set up PIN with pin lock type ${pinLockType}`);
            }
            yield this.stateProvider.setUserState(pin_state_USER_KEY_ENCRYPTED_PIN, userKeyEncryptedPin, userId);
        });
    }
    clearPinState(userId) {
        return pin_state_service_implementation_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(userId, "userId");
            yield this.stateProvider.setUserState(pin_state_USER_KEY_ENCRYPTED_PIN, null, userId);
            yield this.stateProvider.setUserState(PIN_PROTECTED_USER_KEY_ENVELOPE_EPHEMERAL, null, userId);
            yield this.stateProvider.setUserState(PIN_PROTECTED_USER_KEY_ENVELOPE_PERSISTENT, null, userId);
        });
    }
    clearEphemeralPinState(userId) {
        return pin_state_service_implementation_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(userId, "userId");
            yield this.stateProvider.setUserState(PIN_PROTECTED_USER_KEY_ENVELOPE_EPHEMERAL, null, userId);
        });
    }
    pinProtectedUserKeyEnvelope$(userId, pinLockType) {
        assertNonNullish(userId, "userId");
        if (pinLockType === "EPHEMERAL") {
            return this.stateProvider
                .getUserState$(PIN_PROTECTED_USER_KEY_ENVELOPE_EPHEMERAL, userId)
                .pipe((0,external_rxjs_namespaceObject.map)((record) => { var _a, _b; return (_b = (_a = record === null || record === void 0 ? void 0 : record[EPHEMERAL_PIN_ENVELOPE_KEY]) === null || _a === void 0 ? void 0 : _a.pin_envelope) !== null && _b !== void 0 ? _b : null; }));
        }
        else if (pinLockType === "PERSISTENT") {
            return this.stateProvider.getUserState$(PIN_PROTECTED_USER_KEY_ENVELOPE_PERSISTENT, userId);
        }
        else {
            throw new Error(`Unsupported PinLockType: ${pinLockType}`);
        }
    }
}

;// ../../libs/common/src/key-management/utils.ts
var key_management_utils_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

function firstValueFromOrThrow(value, name) {
    return key_management_utils_awaiter(this, void 0, void 0, function* () {
        const result = yield (0,external_rxjs_namespaceObject.firstValueFrom)(value);
        if (result == null) {
            throw new Error(`Failed to get ${name}`);
        }
        return result;
    });
}

;// ../../libs/common/src/key-management/pin/pin.service.implementation.ts
var pin_service_implementation_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var pin_service_implementation_addDisposableResource = (undefined && undefined.__addDisposableResource) || function (env, value, async) {
    if (value !== null && value !== void 0) {
        if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
        var dispose, inner;
        if (async) {
            if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
            dispose = value[Symbol.asyncDispose];
        }
        if (dispose === void 0) {
            if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
            dispose = value[Symbol.dispose];
            if (async) inner = dispose;
        }
        if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
        if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
        env.stack.push({ value: value, dispose: dispose, async: async });
    }
    else if (async) {
        env.stack.push({ async: true });
    }
    return value;
};
var pin_service_implementation_disposeResources = (undefined && undefined.__disposeResources) || (function (SuppressedError) {
    return function (env) {
        function fail(e) {
            env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
            env.hasError = true;
        }
        var r, s = 0;
        function next() {
            while (r = env.stack.pop()) {
                try {
                    if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
                    if (r.dispose) {
                        var result = r.dispose.call(r.value);
                        if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
                    }
                    else s |= 1;
                }
                catch (e) {
                    fail(e);
                }
            }
            if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
            if (env.hasError) throw env.error;
        }
        return next();
    };
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
    var e = new Error(message);
    return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
});




class PinService {
    constructor(encryptService, logService, keyService, sdkService, pinStateService) {
        this.encryptService = encryptService;
        this.logService = logService;
        this.keyService = keyService;
        this.sdkService = sdkService;
        this.pinStateService = pinStateService;
    }
    getPinLockType(userId) {
        assertNonNullish(userId, "userId");
        return this.pinStateService.getPinLockType(userId);
    }
    isPinSet(userId) {
        return pin_service_implementation_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(userId, "userId");
            return (yield this.pinStateService.getPinLockType(userId)) !== "DISABLED";
        });
    }
    logout(userId) {
        return pin_service_implementation_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(userId, "userId");
            yield this.pinStateService.clearPinState(userId);
        });
    }
    userUnlocked(userId) {
        return pin_service_implementation_awaiter(this, void 0, void 0, function* () {
            if ((yield this.pinStateService.getPinLockType(userId)) === "EPHEMERAL" &&
                !(yield this.isPinDecryptionAvailable(userId))) {
                this.logService.info("[Pin Service] On first unlock: Setting up ephemeral PIN");
                // On first unlock, set the ephemeral pin envelope, if it is not set yet
                const pin = yield this.getPin(userId);
                yield this.setPin(pin, "EPHEMERAL", userId);
            }
        });
    }
    getPin(userId) {
        return pin_service_implementation_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(userId, "userId");
            const userKey = yield firstValueFromOrThrow(this.keyService.userKey$(userId), "userKey");
            const userKeyEncryptedPin = yield firstValueFromOrThrow(this.pinStateService.userKeyEncryptedPin$(userId), "userKeyEncryptedPin");
            return this.encryptService.decryptString(userKeyEncryptedPin, userKey);
        });
    }
    setPin(pin, pinLockType, userId) {
        return pin_service_implementation_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(pin, "pin");
            assertNonNullish(pinLockType, "pinLockType");
            assertNonNullish(userId, "userId");
            // Use the sdk to create an enrollment, not yet persisting it to state
            const { pinProtectedUserKeyEnvelope, userKeyEncryptedPin } = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkService.userClient$(userId).pipe((0,external_rxjs_namespaceObject.map)((sdk) => {
                const env_1 = { stack: [], error: void 0, hasError: false };
                try {
                    const ref = pin_service_implementation_addDisposableResource(env_1, sdk.take(), false);
                    return ref.value.crypto().enroll_pin(pin);
                }
                catch (e_1) {
                    env_1.error = e_1;
                    env_1.hasError = true;
                }
                finally {
                    pin_service_implementation_disposeResources(env_1);
                }
            })));
            yield this.pinStateService.setPinState(userId, pinProtectedUserKeyEnvelope, userKeyEncryptedPin, pinLockType);
        });
    }
    unsetPin(userId) {
        return pin_service_implementation_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(userId, "userId");
            yield this.pinStateService.clearPinState(userId);
        });
    }
    isPinDecryptionAvailable(userId) {
        return pin_service_implementation_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(userId, "userId");
            const pinLockType = yield this.pinStateService.getPinLockType(userId);
            switch (pinLockType) {
                case "DISABLED":
                    return false;
                case "PERSISTENT":
                    // The above getPinLockType call ensures that we have either a PinKeyEncryptedUserKey or PinProtectedKeyEnvelope set.
                    return true;
                case "EPHEMERAL": {
                    // The above getPinLockType call ensures that we have a UserKeyEncryptedPin set.
                    // However, we must additively check to ensure that we have a set PinKeyEncryptedUserKeyEphemeral, since
                    // this is only available after first unlock
                    const ephemeralPinProtectedKeyEnvelope = yield this.pinStateService.getPinProtectedUserKeyEnvelope(userId, "EPHEMERAL");
                    return ephemeralPinProtectedKeyEnvelope != null;
                }
                default: {
                    // Compile-time check for exhaustive switch
                    const _exhaustiveCheck = pinLockType;
                    throw new Error(`Unexpected pinLockType: ${_exhaustiveCheck}`);
                }
            }
        });
    }
    decryptUserKeyWithPin(pin, userId) {
        return pin_service_implementation_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(pin, "pin");
            assertNonNullish(userId, "userId");
            this.logService.info("[Pin Service] Pin-unlock via PinProtectedUserKeyEnvelope");
            const pinLockType = yield this.pinStateService.getPinLockType(userId);
            const envelope = yield this.pinStateService.getPinProtectedUserKeyEnvelope(userId, pinLockType);
            try {
                // Use the sdk to create an enrollment, not yet persisting it to state
                const startTime = performance.now();
                const userKeyBytes = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkService.client$.pipe((0,external_rxjs_namespaceObject.map)((sdk) => {
                    if (!sdk) {
                        throw new Error("SDK not available");
                    }
                    return sdk.crypto().unseal_password_protected_key_envelope(pin, envelope);
                })));
                this.logService.measure(startTime, "Crypto", "PinService", "UnsealPinEnvelope");
                return new SymmetricCryptoKey(userKeyBytes);
            }
            catch (error) {
                this.logService.error(`Failed to unseal pin: ${error}`);
                return null;
            }
        });
    }
}

;// ../../libs/common/src/key-management/security-state/services/security-state.service.ts

class DefaultSecurityStateService {
    constructor(accountCryptographicStateService) {
        this.accountCryptographicStateService = accountCryptographicStateService;
    }
    // Emits the provided user's security state, or null if there is no security state present for the user.
    accountSecurityState$(userId) {
        return this.accountCryptographicStateService.accountCryptographicState$(userId).pipe((0,external_rxjs_namespaceObject.map)((cryptographicState) => {
            if (cryptographicState == null) {
                return null;
            }
            if ("V2" in cryptographicState) {
                return cryptographicState.V2.security_state;
            }
            else {
                return null;
            }
        }));
    }
}

;// ../../libs/common/src/tools/send/send-kdf.ts
const SEND_KDF_ITERATIONS = 100000;

;// ../../libs/common/src/key-management/sends/services/default-send-password.service.ts
var default_send_password_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

class DefaultSendPasswordService {
    constructor(cryptoFunctionService) {
        this.cryptoFunctionService = cryptoFunctionService;
    }
    hashPassword(password, keyMaterial) {
        return default_send_password_service_awaiter(this, void 0, void 0, function* () {
            if (!password || !keyMaterial) {
                throw new Error("Password and key material are required.");
            }
            // Derive a password hash using the key material.
            const passwordHash = yield this.cryptoFunctionService.pbkdf2(password, keyMaterial, "sha256", SEND_KDF_ITERATIONS);
            return passwordHash;
        });
    }
}

;// ../../libs/common/src/platform/services/app-id.service.ts
var app_id_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

const app_id_service_APP_ID_KEY = "global_applicationId_appId";
const app_id_service_ANONYMOUS_APP_ID_KEY = "global_applicationId_appId";
class AppIdService {
    constructor(storageService, logService) {
        this.storageService = storageService;
        this.logService = logService;
    }
    getAppId() {
        return app_id_service_awaiter(this, void 0, void 0, function* () {
            this.logService.info("Retrieving application id");
            return yield this.getEnsuredValue(app_id_service_APP_ID_KEY);
        });
    }
    getAnonymousAppId() {
        return app_id_service_awaiter(this, void 0, void 0, function* () {
            return yield this.getEnsuredValue(app_id_service_ANONYMOUS_APP_ID_KEY);
        });
    }
    getEnsuredValue(key) {
        return app_id_service_awaiter(this, void 0, void 0, function* () {
            let value = yield this.storageService.get(key);
            if (value == null) {
                value = utils_Utils.newGuid();
                yield this.storageService.save(key, value);
            }
            return value;
        });
    }
}

;// ../../libs/common/src/platform/models/response/server-config.response.ts


class ServerConfigResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.featureStates = {};
        if (response == null) {
            return;
        }
        this.version = this.getResponseProperty("Version");
        this.gitHash = this.getResponseProperty("GitHash");
        this.server = new ThirdPartyServerConfigResponse(this.getResponseProperty("Server"));
        this.environment = new EnvironmentServerConfigResponse(this.getResponseProperty("Environment"));
        this.featureStates = this.getResponseProperty("FeatureStates");
        this.push = new PushSettingsConfigResponse(this.getResponseProperty("Push"));
        this.settings = new ServerSettings(this.getResponseProperty("Settings"));
        this.communication = new CommunicationServerConfigResponse(this.getResponseProperty("Communication"));
    }
}
class PushSettingsConfigResponse extends BaseResponse {
    constructor(data = null) {
        super(data);
        if (data == null) {
            return;
        }
        this.pushTechnology = this.getResponseProperty("PushTechnology");
        this.vapidPublicKey = this.getResponseProperty("VapidPublicKey");
    }
}
class EnvironmentServerConfigResponse extends BaseResponse {
    constructor(data = null) {
        super(data);
        if (data == null) {
            return;
        }
        this.cloudRegion = this.getResponseProperty("CloudRegion");
        this.vault = this.getResponseProperty("Vault");
        this.api = this.getResponseProperty("Api");
        this.identity = this.getResponseProperty("Identity");
        this.notifications = this.getResponseProperty("Notifications");
        this.sso = this.getResponseProperty("Sso");
        this.fillAssistRules = this.getResponseProperty("FillAssistRules");
    }
}
class ThirdPartyServerConfigResponse extends BaseResponse {
    constructor(data = null) {
        super(data);
        if (data == null) {
            return;
        }
        this.name = this.getResponseProperty("Name");
        this.url = this.getResponseProperty("Url");
    }
}
class CommunicationServerConfigResponse extends BaseResponse {
    constructor(data = null) {
        super(data);
        if (data == null) {
            return;
        }
        this.bootstrap = new BootstrapServerConfigResponse(this.getResponseProperty("Bootstrap"));
    }
}
class BootstrapServerConfigResponse extends BaseResponse {
    constructor(data = null) {
        super(data);
        if (data == null) {
            return;
        }
        this.type = this.getResponseProperty("Type");
        this.idpLoginUrl = this.getResponseProperty("IdpLoginUrl");
        this.cookieName = this.getResponseProperty("CookieName");
        this.cookieDomain = this.getResponseProperty("CookieDomain");
    }
}

;// ../../libs/common/src/platform/services/config/config-api.service.ts
var config_api_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

class ConfigApiService {
    constructor(apiService) {
        this.apiService = apiService;
    }
    get(userId) {
        return config_api_service_awaiter(this, void 0, void 0, function* () {
            // Authentication adds extra context to config responses, if the user has an access token, we want to use it
            // We don't particularly care about ensuring the token is valid and not expired, just that it exists
            let r;
            if (userId == null) {
                r = yield this.apiService.send("GET", "/config", null, false, true);
            }
            else {
                r = yield this.apiService.send("GET", "/config", null, userId, true);
            }
            return new ServerConfigResponse(r);
        });
    }
}

;// ../../libs/common/src/platform/services/container.service.ts
class ContainerService {
    constructor(keyService, encryptService) {
        this.keyService = keyService;
        this.encryptService = encryptService;
    }
    attachToGlobal(global) {
        if (!global.bitwardenContainerService) {
            global.bitwardenContainerService = this;
        }
    }
    /**
     * @throws Will throw if KeyService was not instantiated and provided to the ContainerService constructor
     */
    getKeyService() {
        if (this.keyService == null) {
            throw new Error("ContainerService.keyService not initialized.");
        }
        return this.keyService;
    }
    /**
     * @throws Will throw if EncryptService was not instantiated and provided to the ContainerService constructor
     */
    getEncryptService() {
        if (this.encryptService == null) {
            throw new Error("ContainerService.encryptService not initialized.");
        }
        return this.encryptService;
    }
}

;// ../../libs/common/src/platform/services/default-environment.service.ts
var default_environment_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore




class EnvironmentUrls {
    constructor() {
        this.base = null;
        this.api = null;
        this.identity = null;
        this.icons = null;
        this.notifications = null;
        this.events = null;
        this.webVault = null;
        this.keyConnector = null;
    }
}
class EnvironmentState {
    static fromJSON(obj) {
        return Object.assign(new EnvironmentState(), obj);
    }
}
const GLOBAL_ENVIRONMENT_KEY = new KeyDefinition(ENVIRONMENT_DISK, "environment", {
    deserializer: EnvironmentState.fromJSON,
});
const USER_ENVIRONMENT_KEY = new UserKeyDefinition(ENVIRONMENT_DISK, "environment", {
    deserializer: EnvironmentState.fromJSON,
    clearOn: ["logout"],
});
const GLOBAL_CLOUD_REGION_KEY = new KeyDefinition(ENVIRONMENT_MEMORY, "cloudRegion", {
    deserializer: (b) => b,
});
const USER_CLOUD_REGION_KEY = new UserKeyDefinition(ENVIRONMENT_MEMORY, "cloudRegion", {
    deserializer: (b) => b,
    clearOn: ["logout"],
});
/**
 * The production regions available for selection.
 *
 * In the future we desire to load these urls from the config endpoint.
 */
const PRODUCTION_REGIONS = [
    {
        key: Region.US,
        domain: "bitwarden.com",
        urls: {
            base: null,
            api: "https://api.bitwarden.com",
            identity: "https://identity.bitwarden.com",
            icons: "https://icons.bitwarden.net",
            webVault: "https://vault.bitwarden.com",
            notifications: "https://notifications.bitwarden.com",
            events: "https://events.bitwarden.com",
            scim: "https://scim.bitwarden.com",
        },
    },
    {
        key: Region.EU,
        domain: "bitwarden.eu",
        urls: {
            base: null,
            api: "https://api.bitwarden.eu",
            identity: "https://identity.bitwarden.eu",
            icons: "https://icons.bitwarden.eu",
            webVault: "https://vault.bitwarden.eu",
            notifications: "https://notifications.bitwarden.eu",
            events: "https://events.bitwarden.eu",
            scim: "https://scim.bitwarden.eu",
        },
    },
];
/**
 * The default region when starting the app.
 */
const DEFAULT_REGION = Region.US;
/**
 * The default region configuration.
 */
const DEFAULT_REGION_CONFIG = PRODUCTION_REGIONS.find((r) => r.key === DEFAULT_REGION);
class DefaultEnvironmentService {
    constructor(stateProvider, accountService, additionalRegionConfigs = []) {
        this.stateProvider = stateProvider;
        this.accountService = accountService;
        this.additionalRegionConfigs = additionalRegionConfigs;
        // We intentionally don't want the helper on account service, we want the null back if there is no active user
        this.activeAccountId$ = this.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.map)((a) => a === null || a === void 0 ? void 0 : a.id));
        this.globalState = this.stateProvider.getGlobal(GLOBAL_ENVIRONMENT_KEY);
        this.globalCloudRegionState = this.stateProvider.getGlobal(GLOBAL_CLOUD_REGION_KEY);
        const account$ = this.activeAccountId$.pipe(
        // Use == here to not trigger on undefined -> null transition
        (0,external_rxjs_namespaceObject.distinctUntilChanged)((oldUserId, newUserId) => oldUserId == newUserId));
        this.globalEnvironment$ = this.stateProvider
            .getGlobal(GLOBAL_ENVIRONMENT_KEY)
            .state$.pipe((0,external_rxjs_namespaceObject.map)((state) => this.buildEnvironment(state === null || state === void 0 ? void 0 : state.region, state === null || state === void 0 ? void 0 : state.urls)));
        // The current environment emitted by environment$ can come from two sources: the "global" environment,
        // which represents the environment used by the application before a user authenticates, and the "user" environment,
        // which represents the environment of an authenticated account using the application.
        // We preference the user environment, only falling back to the global environment if a user is not logged in.
        // However, there does exist the possibility that - due to timing of state updates - the active userId state may
        // be cleared after the user environment state.
        // To handle this, we fall back to the global state as a last resort, if the user state is not set.
        const globalEnvState$ = this.stateProvider.getGlobal(GLOBAL_ENVIRONMENT_KEY).state$;
        this.environment$ = account$.pipe((0,external_rxjs_namespaceObject.switchMap)((userId) => {
            if (!userId) {
                return globalEnvState$;
            }
            return this.stateProvider
                .getUser(userId, USER_ENVIRONMENT_KEY)
                .state$.pipe((0,external_rxjs_namespaceObject.switchMap)((userState) => (userState != null ? (0,external_rxjs_namespaceObject.of)(userState) : globalEnvState$)));
        }), (0,external_rxjs_namespaceObject.map)((state) => {
            return this.buildEnvironment(state === null || state === void 0 ? void 0 : state.region, state === null || state === void 0 ? void 0 : state.urls);
        }));
        const globalCloudRegionState$ = this.stateProvider.getGlobal(GLOBAL_CLOUD_REGION_KEY).state$;
        this.cloudWebVaultUrl$ = account$.pipe((0,external_rxjs_namespaceObject.switchMap)((userId) => {
            if (!userId) {
                return globalCloudRegionState$;
            }
            return this.stateProvider
                .getUser(userId, USER_CLOUD_REGION_KEY)
                .state$.pipe((0,external_rxjs_namespaceObject.switchMap)((userState) => (userState != null ? (0,external_rxjs_namespaceObject.of)(userState) : globalCloudRegionState$)));
        }), (0,external_rxjs_namespaceObject.map)((region) => {
            if (region != null) {
                const config = this.getRegionConfig(region);
                if (config != null) {
                    return config.urls.webVault;
                }
            }
            return DEFAULT_REGION_CONFIG.urls.webVault;
        }));
    }
    availableRegions() {
        return PRODUCTION_REGIONS.concat(this.additionalRegionConfigs);
    }
    /**
     * Get the region configuration for the given region.
     */
    getRegionConfig(region) {
        return this.availableRegions().find((r) => r.key === region);
    }
    setEnvironment(region, urls) {
        return default_environment_service_awaiter(this, void 0, void 0, function* () {
            // Unknown regions are treated as self-hosted
            if (this.getRegionConfig(region) == null) {
                region = Region.SelfHosted;
            }
            // If self-hosted ensure urls are valid else fallback to default region
            if (region == Region.SelfHosted && isEmpty(urls)) {
                region = DEFAULT_REGION;
            }
            if (region != Region.SelfHosted) {
                yield this.globalState.update(() => ({
                    region: region,
                    urls: null,
                }));
                return null;
            }
            else {
                // Clean the urls
                urls.base = formatUrl(urls.base);
                urls.webVault = formatUrl(urls.webVault);
                urls.api = formatUrl(urls.api);
                urls.identity = formatUrl(urls.identity);
                urls.icons = formatUrl(urls.icons);
                urls.notifications = formatUrl(urls.notifications);
                urls.events = formatUrl(urls.events);
                urls.keyConnector = formatUrl(urls.keyConnector);
                urls.scim = null;
                yield this.globalState.update(() => ({
                    region: region,
                    urls: {
                        base: urls.base,
                        api: urls.api,
                        identity: urls.identity,
                        webVault: urls.webVault,
                        icons: urls.icons,
                        notifications: urls.notifications,
                        events: urls.events,
                        keyConnector: urls.keyConnector,
                    },
                }));
                return urls;
            }
        });
    }
    /**
     * Helper for building the environment from state. Performs some general sanitization to avoid invalid regions and urls.
     */
    buildEnvironment(region, urls) {
        // Unknown regions are treated as self-hosted
        if (this.getRegionConfig(region) == null) {
            region = Region.SelfHosted;
        }
        // If self-hosted ensure urls are valid else fallback to default region
        if (region == Region.SelfHosted && isEmpty(urls)) {
            region = DEFAULT_REGION;
        }
        // Load urls from region config
        if (region != Region.SelfHosted) {
            const regionConfig = this.getRegionConfig(region);
            if (regionConfig != null) {
                return new CloudEnvironment(regionConfig);
            }
        }
        return new SelfHostedEnvironment(urls);
    }
    setCloudRegion(userId, region) {
        return default_environment_service_awaiter(this, void 0, void 0, function* () {
            if (userId == null) {
                yield this.globalCloudRegionState.update(() => region);
            }
            else {
                yield this.stateProvider.getUser(userId, USER_CLOUD_REGION_KEY).update(() => region);
            }
        });
    }
    getEnvironment$(userId) {
        return this.stateProvider.getUser(userId, USER_ENVIRONMENT_KEY).state$.pipe((0,external_rxjs_namespaceObject.map)((state) => {
            return this.buildEnvironment(state === null || state === void 0 ? void 0 : state.region, state === null || state === void 0 ? void 0 : state.urls);
        }));
    }
    /**
     * @deprecated Use getEnvironment$ instead.
     */
    getEnvironment(userId) {
        return default_environment_service_awaiter(this, void 0, void 0, function* () {
            // Add backwards compatibility support for null userId
            const definedUserId = userId !== null && userId !== void 0 ? userId : (yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.activeAccountId$));
            return (0,external_rxjs_namespaceObject.firstValueFrom)(this.getEnvironment$(definedUserId));
        });
    }
    seedUserEnvironment(userId) {
        return default_environment_service_awaiter(this, void 0, void 0, function* () {
            const global = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.globalState.state$);
            yield this.stateProvider.getUser(userId, USER_ENVIRONMENT_KEY).update(() => global);
        });
    }
}
function formatUrl(url) {
    if (url == null || url === "") {
        return null;
    }
    url = url.replace(/\/+$/g, "");
    if (!url.startsWith("http://") && !url.startsWith("https://")) {
        url = "https://" + url;
    }
    return url.trim();
}
function isEmpty(u) {
    if (u == null) {
        return true;
    }
    return (u.base == null &&
        u.webVault == null &&
        u.api == null &&
        u.identity == null &&
        u.icons == null &&
        u.notifications == null &&
        u.events == null);
}
class UrlEnvironment {
    constructor(region, urls) {
        this.region = region;
        this.urls = urls;
        // Scim is always null for self-hosted
        if (region == Region.SelfHosted) {
            this.urls.scim = null;
        }
    }
    getRegion() {
        return this.region;
    }
    getUrls() {
        return {
            base: this.urls.base,
            webVault: this.urls.webVault,
            api: this.urls.api,
            identity: this.urls.identity,
            icons: this.urls.icons,
            notifications: this.urls.notifications,
            events: this.urls.events,
            keyConnector: this.urls.keyConnector,
            scim: this.urls.scim,
        };
    }
    hasBaseUrl() {
        return this.urls.base != null;
    }
    getWebVaultUrl() {
        return this.getUrl("webVault", "");
    }
    getApiUrl() {
        return this.getUrl("api", "/api");
    }
    getEventsUrl() {
        return this.getUrl("events", "/events");
    }
    getIconsUrl() {
        return this.getUrl("icons", "/icons");
    }
    getIdentityUrl() {
        return this.getUrl("identity", "/identity");
    }
    getKeyConnectorUrl() {
        return this.urls.keyConnector;
    }
    getNotificationsUrl() {
        return this.getUrl("notifications", "/notifications");
    }
    getScimUrl() {
        if (this.urls.scim != null) {
            return this.urls.scim + "/v2";
        }
        return this.getWebVaultUrl() === "https://vault.bitwarden.com"
            ? "https://scim.bitwarden.com/v2"
            : this.getWebVaultUrl() + "/scim/v2";
    }
    getSendUrl() {
        return this.getWebVaultUrl() === "https://vault.bitwarden.com"
            ? "https://send.bitwarden.com/#"
            : this.getWebVaultUrl() + "/#/send/";
    }
    /**
     * Presume that if the region is not self-hosted, it is cloud.
     */
    isCloud() {
        return this.region !== Region.SelfHosted;
    }
    /**
     * Helper for getting an URL.
     *
     * @param key Key of the URL to get from URLs
     * @param baseSuffix Suffix to append to the base URL if the url is not set
     * @returns
     */
    getUrl(key, baseSuffix) {
        if (this.urls[key] != null) {
            return this.urls[key];
        }
        if (this.urls.base) {
            return this.urls.base + baseSuffix;
        }
        return DEFAULT_REGION_CONFIG.urls[key];
    }
}
/**
 * Denote a cloud environment.
 */
class CloudEnvironment extends UrlEnvironment {
    constructor(config) {
        super(config.key, config.urls);
        this.config = config;
    }
    /**
     * Cloud always returns nice urls, i.e. bitwarden.com instead of vault.bitwarden.com.
     */
    getHostname() {
        return this.config.domain;
    }
}
class SelfHostedEnvironment extends UrlEnvironment {
    constructor(urls) {
        super(Region.SelfHosted, urls);
    }
    getHostname() {
        return utils_Utils.getHost(this.getWebVaultUrl());
    }
}

;// ../../libs/common/src/platform/services/file-upload/azure-file-upload.service.ts
var azure_file_upload_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};


const MAX_SINGLE_BLOB_UPLOAD_SIZE = 256 * 1024 * 1024; // 256 MiB
const MAX_BLOCKS_PER_BLOB = 50000;
class AzureFileUploadService {
    constructor(logService, apiService, configService) {
        this.logService = logService;
        this.apiService = apiService;
        this.configService = configService;
    }
    upload(url, data, renewalCallback, options) {
        return azure_file_upload_service_awaiter(this, void 0, void 0, function* () {
            const progressEnabled = yield this.configService.getFeatureFlag(feature_flag_enum_FeatureFlag.PM34410AttachmentUploadProgress);
            if (progressEnabled) {
                if (data.buffer.byteLength <= MAX_SINGLE_BLOB_UPLOAD_SIZE) {
                    return yield this.azureUploadBlob(url, data, options);
                }
                else {
                    return yield this.azureUploadBlocks(url, data, renewalCallback, options);
                }
            }
            else {
                if (data.buffer.byteLength <= MAX_SINGLE_BLOB_UPLOAD_SIZE) {
                    return yield this.azureUploadBlob(url, data);
                }
                else {
                    return yield this.legacyAzureUploadBlocks(url, data, renewalCallback);
                }
            }
        });
    }
    azureUploadBlob(url, data, options) {
        return azure_file_upload_service_awaiter(this, void 0, void 0, function* () {
            const urlObject = utils_Utils.getUrl(url);
            const headers = new Headers({
                "x-ms-date": new Date().toUTCString(),
                "x-ms-version": urlObject.searchParams.get("sv"),
                "Content-Length": data.buffer.byteLength.toString(),
                "x-ms-blob-type": "BlockBlob",
            });
            const request = new Request(url, {
                body: data.buffer,
                cache: "no-store",
                method: "PUT",
                headers: headers,
            });
            const blobResponse = utils_Utils.isBrowser && (options === null || options === void 0 ? void 0 : options.onProgress)
                ? yield this.apiService.nativeXMLHttpRequest(request, options.onProgress)
                : yield this.apiService.nativeFetch(request);
            if (blobResponse.status !== 201) {
                throw new Error(`Failed to create Azure blob: ${blobResponse.status}`);
            }
        });
    }
    azureUploadBlocks(url, data, renewalCallback, options) {
        return azure_file_upload_service_awaiter(this, void 0, void 0, function* () {
            url = yield this.renewUrlIfNecessary(url, renewalCallback);
            const blockUrl = utils_Utils.getUrl(url);
            const blockId = this.encodedBlockId(0); // Only one block supported since max block size exceeds max file size
            blockUrl.searchParams.append("comp", "block");
            blockUrl.searchParams.append("blockid", blockId);
            const blockHeaders = new Headers({
                "x-ms-date": new Date().toUTCString(),
                "x-ms-version": blockUrl.searchParams.get("sv"),
                "Content-Length": data.buffer.byteLength.toString(),
            });
            const blockRequest = new Request(blockUrl.toString(), {
                body: data.buffer,
                cache: "no-store",
                method: "PUT",
                headers: blockHeaders,
            });
            const blockResponse = utils_Utils.isBrowser && (options === null || options === void 0 ? void 0 : options.onProgress)
                ? yield this.apiService.nativeXMLHttpRequest(blockRequest, options.onProgress)
                : yield this.apiService.nativeFetch(blockRequest);
            if (blockResponse.status !== 201) {
                const message = `Unsuccessful block PUT. Received status ${blockResponse.status}`;
                this.logService.error(message + "\n" + (yield blockResponse.json()));
                throw new Error(message);
            }
            url = yield this.renewUrlIfNecessary(url, renewalCallback);
            const blockListUrl = utils_Utils.getUrl(url);
            const blockListXml = this.blockListXml([blockId]);
            blockListUrl.searchParams.append("comp", "blocklist");
            const headers = new Headers({
                "x-ms-date": new Date().toUTCString(),
                "x-ms-version": blockListUrl.searchParams.get("sv"),
                "Content-Length": blockListXml.length.toString(),
            });
            const request = new Request(blockListUrl.toString(), {
                body: blockListXml,
                cache: "no-store",
                method: "PUT",
                headers: headers,
            });
            const response = yield this.apiService.nativeFetch(request);
            if (response.status !== 201) {
                const message = `Unsuccessful block list PUT. Received status ${response.status}`;
                this.logService.error(message + "\n" + (yield response.json()));
                throw new Error(message);
            }
        });
    }
    legacyAzureUploadBlocks(url, data, renewalCallback) {
        return azure_file_upload_service_awaiter(this, void 0, void 0, function* () {
            const baseUrl = utils_Utils.getUrl(url);
            const blockSize = this.getMaxBlockSize(baseUrl.searchParams.get("sv"));
            let blockIndex = 0;
            const numBlocks = Math.ceil(data.buffer.byteLength / blockSize);
            const blocksStaged = [];
            if (numBlocks > MAX_BLOCKS_PER_BLOB) {
                throw new Error(`Cannot upload file, exceeds maximum size of ${blockSize * MAX_BLOCKS_PER_BLOB}`);
            }
            // eslint-disable-next-line
            try {
                while (blockIndex < numBlocks) {
                    url = yield this.renewUrlIfNecessary(url, renewalCallback);
                    const blockUrl = utils_Utils.getUrl(url);
                    const blockId = this.encodedBlockId(blockIndex);
                    blockUrl.searchParams.append("comp", "block");
                    blockUrl.searchParams.append("blockid", blockId);
                    const start = blockIndex * blockSize;
                    const blockData = data.buffer.slice(start, start + blockSize);
                    const blockHeaders = new Headers({
                        "x-ms-date": new Date().toUTCString(),
                        "x-ms-version": blockUrl.searchParams.get("sv"),
                        "Content-Length": blockData.byteLength.toString(),
                    });
                    const blockRequest = new Request(blockUrl.toString(), {
                        body: blockData,
                        cache: "no-store",
                        method: "PUT",
                        headers: blockHeaders,
                    });
                    const blockResponse = yield this.apiService.nativeFetch(blockRequest);
                    if (blockResponse.status !== 201) {
                        const message = `Unsuccessful block PUT. Received status ${blockResponse.status}`;
                        this.logService.error(message + "\n" + (yield blockResponse.json()));
                        throw new Error(message);
                    }
                    blocksStaged.push(blockId);
                    blockIndex++;
                }
                url = yield this.renewUrlIfNecessary(url, renewalCallback);
                const blockListUrl = utils_Utils.getUrl(url);
                const blockListXml = this.blockListXml(blocksStaged);
                blockListUrl.searchParams.append("comp", "blocklist");
                const headers = new Headers({
                    "x-ms-date": new Date().toUTCString(),
                    "x-ms-version": blockListUrl.searchParams.get("sv"),
                    "Content-Length": blockListXml.length.toString(),
                });
                const request = new Request(blockListUrl.toString(), {
                    body: blockListXml,
                    cache: "no-store",
                    method: "PUT",
                    headers: headers,
                });
                const response = yield this.apiService.nativeFetch(request);
                if (response.status !== 201) {
                    const message = `Unsuccessful block list PUT. Received status ${response.status}`;
                    this.logService.error(message + "\n" + (yield response.json()));
                    throw new Error(message);
                }
            }
            catch (e) {
                throw e;
            }
        });
    }
    renewUrlIfNecessary(url, renewalCallback) {
        return azure_file_upload_service_awaiter(this, void 0, void 0, function* () {
            var _a;
            const urlObject = utils_Utils.getUrl(url);
            const expiry = new Date((_a = urlObject.searchParams.get("se")) !== null && _a !== void 0 ? _a : "");
            if (isNaN(expiry.getTime())) {
                expiry.setTime(Date.now() + 3600000);
            }
            if (expiry.getTime() < Date.now() + 1000) {
                return yield renewalCallback();
            }
            return url;
        });
    }
    encodedBlockId(blockIndex) {
        // Encoded blockId max size is 64, so pre-encoding max size is 48
        const utfBlockId = ("000000000000000000000000000000000000000000000000" + blockIndex.toString()).slice(-48);
        return utils_Utils.fromUtf8ToB64(utfBlockId);
    }
    blockListXml(blockIdList) {
        let xml = '<?xml version="1.0" encoding="utf-8"?><BlockList>';
        blockIdList.forEach((blockId) => {
            xml += `<Latest>${blockId}</Latest>`;
        });
        xml += "</BlockList>";
        return xml;
    }
    getMaxBlockSize(version) {
        if (Version.compare(version, "2019-12-12") >= 0) {
            return 4000 * 1024 * 1024; // 4000 MiB
        }
        else if (Version.compare(version, "2016-05-31") >= 0) {
            return 100 * 1024 * 1024; // 100 MiB
        }
        else {
            return 4 * 1024 * 1024; // 4 MiB
        }
    }
}
class Version {
    /**
     * Compares two Azure Versions against each other
     * @param a Version to compare
     * @param b Version to compare
     * @returns a number less than zero if b is newer than a, 0 if equal,
     * and greater than zero if a is newer than b
     */
    static compare(a, b) {
        if (typeof a === "string") {
            a = new Version(a);
        }
        if (typeof b === "string") {
            b = new Version(b);
        }
        return a.year !== b.year
            ? a.year - b.year
            : a.month !== b.month
                ? a.month - b.month
                : a.day !== b.day
                    ? a.day - b.day
                    : 0;
    }
    constructor(version) {
        this.year = 0;
        this.month = 0;
        this.day = 0;
        try {
            const parts = version.split("-").map((v) => Number.parseInt(v, 10));
            this.year = parts[0];
            this.month = parts[1];
            this.day = parts[2];
        }
        catch (_a) {
            // Ignore error
        }
    }
    /**
     * Compares two Azure Versions against each other
     * @param compareTo Version to compare against
     * @returns a number less than zero if compareTo is newer, 0 if equal,
     * and greater than zero if this is greater than compareTo
     */
    compare(compareTo) {
        return Version.compare(this, compareTo);
    }
}

;// ../../libs/common/src/platform/services/file-upload/bitwarden-file-upload.service.ts
var bitwarden_file_upload_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

class BitwardenFileUploadService {
    upload(encryptedFileName, encryptedFileData, apiCall) {
        return bitwarden_file_upload_service_awaiter(this, void 0, void 0, function* () {
            const fd = new FormData();
            if (utils_Utils.isBrowser) {
                const blob = new Blob([encryptedFileData.buffer], {
                    type: "application/octet-stream",
                });
                fd.append("data", blob, encryptedFileName);
            }
            else if (utils_Utils.isNode) {
                fd.append("data", Buffer.from(encryptedFileData.buffer), {
                    filename: encryptedFileName,
                    contentType: "application/octet-stream",
                });
            }
            else {
                throw new Error("Unsupported environment");
            }
            yield apiCall(fd);
        });
    }
}

;// ../../libs/common/src/platform/services/file-upload/file-upload.service.ts
var file_upload_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};



class FileUploadService {
    constructor(logService, apiService, configService) {
        this.logService = logService;
        this.azureFileUploadService = new AzureFileUploadService(logService, apiService, configService);
        this.bitwardenFileUploadService = new BitwardenFileUploadService();
    }
    upload(uploadData, fileName, encryptedFileData, fileUploadMethods, options) {
        return file_upload_service_awaiter(this, void 0, void 0, function* () {
            try {
                switch (uploadData.fileUploadType) {
                    case FileUploadType.Direct:
                        yield this.bitwardenFileUploadService.upload(fileName.encryptedString, encryptedFileData, (fd) => fileUploadMethods.postDirect(fd));
                        break;
                    case FileUploadType.Azure: {
                        yield this.azureFileUploadService.upload(uploadData.url, encryptedFileData, fileUploadMethods.renewFileUploadUrl, options);
                        break;
                    }
                    default:
                        throw new Error("Unknown file upload type");
                }
            }
            catch (e) {
                yield fileUploadMethods.rollback();
                throw e;
            }
        });
    }
}

;// ../../libs/common/src/platform/services/memory-storage.service.ts


;// ../../libs/common/src/state-migrations/index.ts
// Compatibility re-export for @bitwarden/common/state-migrations


;// ../../libs/common/src/platform/services/migration-builder.service.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

class MigrationBuilderService {
    build() {
        var _a;
        return ((_a = this.migrationBuilderCache) !== null && _a !== void 0 ? _a : (this.migrationBuilderCache = createMigrationBuilder()));
    }
}

;// ../../libs/common/src/platform/services/migration-runner.ts
var migration_runner_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};


class MigrationRunner {
    constructor(diskStorage, logService, migrationBuilderService, clientType) {
        this.diskStorage = diskStorage;
        this.logService = logService;
        this.migrationBuilderService = migrationBuilderService;
        this.clientType = clientType;
    }
    run() {
        return migration_runner_awaiter(this, void 0, void 0, function* () {
            const migrationHelper = new MigrationHelper(yield currentVersion(this.diskStorage, this.logService), this.diskStorage, this.logService, "general", this.clientType);
            if (migrationHelper.currentVersion < 0) {
                // Cannot determine state, assuming empty so we don't repeatedly apply a migration.
                yield this.diskStorage.save("stateVersion", CURRENT_VERSION);
                return;
            }
            const migrationBuilder = this.migrationBuilderService.build();
            yield migrationBuilder.migrate(migrationHelper);
        });
    }
    waitForCompletion() {
        return migration_runner_awaiter(this, void 0, void 0, function* () {
            yield waitForMigrations(this.diskStorage, this.logService);
        });
    }
}

;// ../../libs/common/src/platform/services/sdk/default-sdk-client-factory.ts
var default_sdk_client_factory_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

/**
 * Default SDK client factory.
 */
class DefaultSdkClientFactory {
    /**
     * Initializes a Password Manager client. Assumes the SDK is already loaded.
     * @param args Password Manager client constructor parameters
     * @returns A PasswordManagerClient
     */
    createSdkClient(...args) {
        return default_sdk_client_factory_awaiter(this, void 0, void 0, function* () {
            return Promise.resolve(new bitwarden_wasm_internal_bg/* PasswordManagerClient */.cPU(...args));
        });
    }
}

;// ../../libs/common/src/platform/misc/compare-values.ts
/**
 * Performs deep equality check between two values
 *
 * NOTE: This method uses JSON.stringify to compare objects, which may return false
 * for objects with the same properties but in different order. If order-insensitive
 * comparison becomes necessary in future, consider updating this method to use a comparison
 * that checks for property existence and value equality without regard to order.
 */
function compareValues(value1, value2) {
    if (value1 == null && value2 == null) {
        return true;
    }
    if (value1 && value2 == null) {
        return false;
    }
    if (value1 == null && value2) {
        return false;
    }
    if (typeof value1 !== "object" || typeof value2 !== "object") {
        return value1 === value2;
    }
    return JSON.stringify(value1) === JSON.stringify(value2);
}

;// ../../libs/common/src/platform/misc/reference-counting/rc.ts
/**
 * Reference counted disposable value.
 * This class is used to manage the lifetime of a value that needs to be
 * freed of at a specific time but might still be in-use when that happens.
 */
class Rc {
    constructor(value) {
        this.markedForDisposal = false;
        this.refCount = 0;
        this.value = value;
    }
    /**
     * Use this function when you want to use the underlying object.
     * This will guarantee that you have a reference to the object
     * and that it won't be freed until your reference goes out of scope.
     *
     * This function must be used with the `using` keyword.
     *
     * @example
     * ```typescript
     * function someFunction(rc: Rc<SomeValue>) {
     *   using reference = rc.take();
     *   reference.value.doSomething();
     *   // reference is automatically disposed here
     * }
     * ```
     *
     * @returns The value.
     */
    take() {
        if (this.markedForDisposal) {
            throw new Error("Cannot take a reference to a value marked for disposal");
        }
        this.refCount++;
        return new Ref(() => this.release(), this.value);
    }
    /**
     * Mark this Rc for disposal. When the refCount reaches 0, the value
     * will be freed.
     */
    markForDisposal() {
        this.markedForDisposal = true;
        this.freeIfPossible();
    }
    release() {
        this.refCount--;
        this.freeIfPossible();
    }
    freeIfPossible() {
        if (this.refCount === 0 && this.markedForDisposal) {
            this.value.free();
        }
    }
}
class Ref {
    constructor(release, value) {
        this.release = release;
        this.value = value;
    }
    [Symbol.dispose]() {
        this.release();
    }
}

;// ../../libs/common/src/vault/services/key-state/ciphers.state.ts



const ENCRYPTED_CIPHERS = UserKeyDefinition.record(CIPHERS_DISK, "ciphers", {
    deserializer: (obj) => CipherData.fromJSON(obj),
    clearOn: ["logout"],
});
const DECRYPTED_CIPHERS = UserKeyDefinition.record(CIPHERS_MEMORY, "decryptedCiphers", {
    deserializer: (cipher) => CipherView.fromJSON(cipher),
    clearOn: ["logout", "lock"],
});
const FAILED_DECRYPTED_CIPHERS = UserKeyDefinition.array(CIPHERS_MEMORY, "failedDecryptedCiphers", {
    deserializer: (cipher) => CipherView.fromJSON(cipher),
    clearOn: ["logout", "lock"],
});
const LOCAL_DATA_KEY = new UserKeyDefinition(CIPHERS_DISK_LOCAL, "localData", {
    deserializer: (localData) => localData,
    clearOn: ["logout"],
});
const ADD_EDIT_CIPHER_INFO_KEY = new UserKeyDefinition(CIPHERS_MEMORY, "addEditCipherInfo", {
    deserializer: (addEditCipherInfo) => {
        if (addEditCipherInfo == null) {
            return null;
        }
        const cipher = (addEditCipherInfo === null || addEditCipherInfo === void 0 ? void 0 : addEditCipherInfo.cipher.toJSON) != null
            ? addEditCipherInfo.cipher
            : CipherView.fromJSON(addEditCipherInfo === null || addEditCipherInfo === void 0 ? void 0 : addEditCipherInfo.cipher);
        return { cipher, collectionIds: addEditCipherInfo.collectionIds };
    },
    clearOn: ["logout", "lock"],
});

;// ../../libs/common/src/vault/models/domain/cipher-sdk-mapper.ts


class CipherRecordMapper {
    userKeyDefinition() {
        return ENCRYPTED_CIPHERS;
    }
    toSdk(value) {
        return new Cipher(value).toSdkCipher();
    }
    fromSdk(value) {
        const cipher = Cipher.fromSdkCipher(value);
        return cipher.toCipherData();
    }
}

;// ../../libs/common/src/key-management/ephemeral-pin-envelope-mapper.ts

class EphemeralPinEnvelopeMapper {
    userKeyDefinition() {
        return PIN_PROTECTED_USER_KEY_ENVELOPE_EPHEMERAL;
    }
    toSdk(value) {
        return value;
    }
    fromSdk(value) {
        return value;
    }
}

;// ../../libs/common/src/platform/services/key-state/local-user-data-key.state.ts

const LOCAL_USER_DATA_KEY = UserKeyDefinition.record(CRYPTO_DISK, "localUserDataKey", {
    deserializer: (obj) => obj,
    clearOn: ["logout"],
    // Prevents the state from caching and rxjs observable becoming hot observable.
    cleanupDelayMs: 0,
});

;// ../../libs/common/src/key-management/local-user-data-key-mapper.ts

class LocalUserDataKeyRecordMapper {
    userKeyDefinition() {
        return LOCAL_USER_DATA_KEY;
    }
    toSdk(value) {
        return { wrapped_key: value };
    }
    fromSdk(value) {
        return value.wrapped_key;
    }
}

;// ../../libs/common/src/key-management/user-key-mapper.ts


class UserKeyRecordMapper {
    userKeyDefinition() {
        return USER_KEY;
    }
    toSdk(value) {
        return { decrypted_user_key: value.toBase64() };
    }
    fromSdk(value) {
        return SymmetricCryptoKey.fromString(value.decrypted_user_key);
    }
}

;// ../../libs/common/src/platform/services/sdk/client-managed-state.ts
var client_managed_state_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var client_managed_state_rest = (undefined && undefined.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};





function initializeClientManagedState(userId, stateClient, stateProvider) {
    return client_managed_state_awaiter(this, void 0, void 0, function* () {
        stateClient.register_client_managed_repositories({
            cipher: new RepositoryRecord(userId, stateProvider, new CipherRecordMapper()),
            folder: null,
            user_key_state: new RepositoryRecord(userId, stateProvider, new UserKeyRecordMapper()),
            local_user_data_key_state: new RepositoryRecord(userId, stateProvider, new LocalUserDataKeyRecordMapper()),
            ephemeral_pin_envelope_state: new RepositoryRecord(userId, stateProvider, new EphemeralPinEnvelopeMapper()),
            organization_shared_key: null,
        });
    });
}
class RepositoryRecord {
    constructor(userId, stateProvider, mapper) {
        this.userId = userId;
        this.stateProvider = stateProvider;
        this.mapper = mapper;
    }
    get(id) {
        return client_managed_state_awaiter(this, void 0, void 0, function* () {
            const record = yield this.getRecord();
            const element = record[id];
            return element ? this.mapper.toSdk(element) : null;
        });
    }
    list() {
        return client_managed_state_awaiter(this, void 0, void 0, function* () {
            const record = yield this.getRecord();
            return Object.values(record).map((element) => this.mapper.toSdk(element));
        });
    }
    set(id, value) {
        return client_managed_state_awaiter(this, void 0, void 0, function* () {
            yield this.getUserState().update((state) => (Object.assign(Object.assign({}, (state !== null && state !== void 0 ? state : {})), { [id]: this.mapper.fromSdk(value) })));
        });
    }
    setBulk(values) {
        return client_managed_state_awaiter(this, void 0, void 0, function* () {
            const mapped = Object.fromEntries(values.map(([id, value]) => [id, this.mapper.fromSdk(value)]));
            yield this.getUserState().update((state) => (Object.assign(Object.assign({}, (state !== null && state !== void 0 ? state : {})), mapped)));
        });
    }
    remove(id) {
        return client_managed_state_awaiter(this, void 0, void 0, function* () {
            yield this.getUserState().update((state) => {
                if (!state || !(id in state)) {
                    return state;
                }
                // Rest sibling
                // eslint-disable-next-line @typescript-eslint/no-unused-vars
                const _a = state, _b = id, _unused = _a[_b], rest = client_managed_state_rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
                return rest;
            });
        });
    }
    removeBulk(keys) {
        return client_managed_state_awaiter(this, void 0, void 0, function* () {
            yield this.getUserState().update((state) => {
                if (!state || !keys.some((key) => key in state)) {
                    return state;
                }
                const keysToRemove = new Set(keys);
                return Object.fromEntries(Object.entries(state).filter(([key]) => !keysToRemove.has(key)));
            });
        });
    }
    removeAll() {
        return client_managed_state_awaiter(this, void 0, void 0, function* () {
            yield this.getUserState().update(() => ({}));
        });
    }
    getUserState() {
        return this.stateProvider.getUser(this.userId, this.mapper.userKeyDefinition());
    }
    getRecord() {
        return client_managed_state_awaiter(this, void 0, void 0, function* () {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.getUserState().state$.pipe((0,external_rxjs_namespaceObject.map)((state) => state !== null && state !== void 0 ? state : {})));
        });
    }
}

;// ../../libs/common/src/platform/services/sdk/default-sdk.service.ts
var default_sdk_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};







// A symbol that represents an overridden client that is explicitly set to undefined,
// blocking the creation of an internal client for that user.
const UnsetClient = Symbol("UnsetClient");
/**
 * A token provider that exposes the access token to the SDK.
 */
class JsTokenProvider {
    constructor(apiService, userId) {
        this.apiService = apiService;
        this.userId = userId;
    }
    get_access_token() {
        return default_sdk_service_awaiter(this, void 0, void 0, function* () {
            if (this.userId == null) {
                return undefined;
            }
            return yield this.apiService.getActiveBearerToken(this.userId);
        });
    }
}
class DefaultSdkService {
    constructor(sdkClientFactory, environmentService, platformUtilsService, accountService, kdfConfigService, keyService, accountCryptographyStateService, apiService, stateProvider, configService, userAgent = null) {
        this.sdkClientFactory = sdkClientFactory;
        this.environmentService = environmentService;
        this.platformUtilsService = platformUtilsService;
        this.accountService = accountService;
        this.kdfConfigService = kdfConfigService;
        this.keyService = keyService;
        this.accountCryptographyStateService = accountCryptographyStateService;
        this.apiService = apiService;
        this.stateProvider = stateProvider;
        this.configService = configService;
        this.userAgent = userAgent;
        this.sdkClientOverrides = new external_rxjs_namespaceObject.BehaviorSubject({});
        this.sdkClientCache = new Map();
        this.client$ = this.environmentService.environment$.pipe((0,external_rxjs_namespaceObject.concatMap)((env) => default_sdk_service_awaiter(this, void 0, void 0, function* () {
            yield SdkLoadService.Ready;
            const settings = yield this.toSettings(env);
            const client = yield this.sdkClientFactory.createSdkClient(new JsTokenProvider(this.apiService), settings);
            yield this.loadFeatureFlags(client);
            return client;
        })), (0,external_rxjs_namespaceObject.shareReplay)({ refCount: true, bufferSize: 1 }));
        this.version$ = this.client$.pipe((0,external_rxjs_namespaceObject.map)((client) => client.version()), (0,external_rxjs_namespaceObject.catchError)(() => "Unsupported"));
    }
    userClient$(userId) {
        return this.sdkClientOverrides.pipe((0,external_rxjs_namespaceObject.takeWhile)((clients) => clients[userId] !== UnsetClient, false), (0,external_rxjs_namespaceObject.map)((clients) => {
            if (clients[userId] === UnsetClient) {
                throw new Error("Encountered UnsetClient even though it should have been filtered out");
            }
            return clients[userId];
        }), (0,external_rxjs_namespaceObject.distinctUntilChanged)(), (0,external_rxjs_namespaceObject.switchMap)((clientOverride) => {
            if (clientOverride) {
                return (0,external_rxjs_namespaceObject.of)(clientOverride);
            }
            return this.internalClient$(userId);
        }), (0,external_rxjs_namespaceObject.takeWhile)((client) => client !== undefined, false), (0,external_rxjs_namespaceObject.throwIfEmpty)(() => new UserNotLoggedInError(userId)));
    }
    setClient(userId, client) {
        const previousValue = this.sdkClientOverrides.value[userId];
        this.sdkClientOverrides.next(Object.assign(Object.assign({}, this.sdkClientOverrides.value), { [userId]: client ? new Rc(client) : UnsetClient }));
        if (previousValue !== UnsetClient && previousValue !== undefined) {
            previousValue.markForDisposal();
        }
    }
    /**
     * This method is used to create a client for a specific user by using the existing state of the application.
     * This methods is a fallback for when no client has been provided by Auth. As Auth starts implementing the
     * client creation, this method will be deprecated.
     * @param userId The user id for which to create the client
     * @returns An observable that emits the client for the user
     */
    internalClient$(userId) {
        const cached = this.sdkClientCache.get(userId);
        if (cached !== undefined) {
            return cached;
        }
        const account$ = this.accountService.accounts$.pipe((0,external_rxjs_namespaceObject.map)((accounts) => accounts[userId]), (0,external_rxjs_namespaceObject.distinctUntilChanged)());
        const kdfParams$ = this.kdfConfigService.getKdfConfig$(userId).pipe((0,external_rxjs_namespaceObject.distinctUntilChanged)());
        const accountCryptographicState$ = this.accountCryptographyStateService
            .accountCryptographicState$(userId)
            .pipe((0,external_rxjs_namespaceObject.distinctUntilChanged)());
        const userKey$ = this.keyService.userKey$(userId).pipe((0,external_rxjs_namespaceObject.distinctUntilChanged)());
        const orgKeys$ = this.keyService.encryptedOrgKeys$(userId).pipe((0,external_rxjs_namespaceObject.distinctUntilChanged)(compareValues));
        const client$ = (0,external_rxjs_namespaceObject.combineLatest)([
            this.environmentService.getEnvironment$(userId),
            account$,
            kdfParams$,
            accountCryptographicState$,
            userKey$,
            orgKeys$,
            SdkLoadService.Ready, // Makes sure we wait (once) for the SDK to be loaded
        ]).pipe(
        // switchMap is required to allow the clean-up logic to be executed when `combineLatest` emits a new value.
        (0,external_rxjs_namespaceObject.switchMap)(([env, account, kdfParams, accountCryptographicState, userKey, orgKeys]) => {
            // Create our own observable to be able to implement clean-up logic
            return new external_rxjs_namespaceObject.Observable((subscriber) => {
                const createAndInitializeClient = () => default_sdk_service_awaiter(this, void 0, void 0, function* () {
                    if (env == null ||
                        kdfParams == null ||
                        accountCryptographicState == null ||
                        userKey == null) {
                        return undefined;
                    }
                    const settings = yield this.toSettings(env);
                    const client = yield this.sdkClientFactory.createSdkClient(new JsTokenProvider(this.apiService, userId), settings);
                    yield this.initializeClient(userId, client, account, kdfParams.toSdkConfig(), userKey, accountCryptographicState, orgKeys);
                    return client;
                });
                let client;
                createAndInitializeClient()
                    .then((c) => {
                    client = c === undefined ? undefined : new Rc(c);
                    subscriber.next(client);
                })
                    .catch((e) => {
                    subscriber.error(e);
                });
                return () => client === null || client === void 0 ? void 0 : client.markForDisposal();
            });
        }), (0,external_rxjs_namespaceObject.tap)({ finalize: () => this.sdkClientCache.delete(userId) }), (0,external_rxjs_namespaceObject.share)({
            connector: () => new external_rxjs_namespaceObject.ReplaySubject(1),
            resetOnRefCountZero: () => (0,external_rxjs_namespaceObject.timer)(1000),
        }));
        this.sdkClientCache.set(userId, client$);
        return client$;
    }
    initializeClient(userId, client, account, kdf, userKey, accountCryptographicState, orgKeys) {
        return default_sdk_service_awaiter(this, void 0, void 0, function* () {
            // Initialize the client managed repositories.
            yield initializeClientManagedState(userId, client.platform().state(), this.stateProvider);
            yield this.loadFeatureFlags(client);
            if (yield this.configService.getFeatureFlag(feature_flag_enum_FeatureFlag.UnlockViaSDK)) {
                yield client.crypto().initialize_user_crypto({
                    userId: asUuid(userId),
                    email: account.email,
                    method: { clientManagedState: {} },
                    kdfParams: kdf,
                    accountCryptographicState: accountCryptographicState,
                });
            }
            else {
                yield client.crypto().initialize_user_crypto({
                    userId: asUuid(userId),
                    email: account.email,
                    method: {
                        decryptedKey: {
                            decrypted_user_key: userKey.toBase64(),
                        },
                    },
                    kdfParams: kdf,
                    accountCryptographicState: accountCryptographicState,
                });
            }
            // We initialize the org crypto even if the org_keys are
            // null to make sure any existing org keys are cleared.
            yield client.crypto().initialize_org_crypto({
                organizationKeys: new Map(Object.entries(orgKeys).map(([k, v]) => [asUuid(k), v.toJSON()])),
            });
        });
    }
    loadFeatureFlags(client) {
        return default_sdk_service_awaiter(this, void 0, void 0, function* () {
            var _a;
            const serverConfig = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.configService.serverConfig$);
            const featureFlagMap = new Map(Object.entries((_a = serverConfig === null || serverConfig === void 0 ? void 0 : serverConfig.featureStates) !== null && _a !== void 0 ? _a : {})
                .filter(([, value]) => typeof value === "boolean") // The SDK only supports boolean feature flags at this time
                .map(([key, value]) => [key, value]));
            yield client.platform().load_flags(featureFlagMap);
        });
    }
    toSettings(env) {
        return default_sdk_service_awaiter(this, void 0, void 0, function* () {
            var _a;
            return {
                apiUrl: env.getApiUrl(),
                identityUrl: env.getIdentityUrl(),
                deviceType: toSdkDevice(this.platformUtilsService.getDevice()),
                bitwardenClientVersion: yield this.platformUtilsService.getApplicationVersionNumber(),
                userAgent: (_a = this.userAgent) !== null && _a !== void 0 ? _a : navigator.userAgent,
            };
        });
    }
}

;// ../../libs/common/src/platform/services/sdk/noop-sdk-client-factory.ts
/**
 * Noop SDK client factory.
 *
 * Used during SDK rollout to prevent bundling the SDK with some applications.
 */
class NoopSdkClientFactory {
    createSdkClient(...args) {
        return Promise.reject(new Error("SDK not available"));
    }
}

;// ../../libs/common/src/platform/services/sdk/register-sdk.service.ts
var register_sdk_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};





// A symbol that represents an overridden client that is explicitly set to undefined,
// blocking the creation of an internal client for that user.
const register_sdk_service_UnsetClient = Symbol("UnsetClient");
/**
 * A token provider that exposes the access token to the SDK.
 */
class register_sdk_service_JsTokenProvider {
    constructor(apiService, userId) {
        this.apiService = apiService;
        this.userId = userId;
    }
    get_access_token() {
        return register_sdk_service_awaiter(this, void 0, void 0, function* () {
            if (this.userId == null) {
                return undefined;
            }
            return yield this.apiService.getActiveBearerToken(this.userId);
        });
    }
}
class DefaultRegisterSdkService {
    constructor(sdkClientFactory, environmentService, platformUtilsService, accountService, apiService, stateProvider, configService, userAgent = null) {
        this.sdkClientFactory = sdkClientFactory;
        this.environmentService = environmentService;
        this.platformUtilsService = platformUtilsService;
        this.accountService = accountService;
        this.apiService = apiService;
        this.stateProvider = stateProvider;
        this.configService = configService;
        this.userAgent = userAgent;
        this.sdkClientOverrides = new external_rxjs_namespaceObject.BehaviorSubject({});
        this.sdkClientCache = new Map();
        this.client$ = this.environmentService.environment$.pipe((0,external_rxjs_namespaceObject.concatMap)((env) => register_sdk_service_awaiter(this, void 0, void 0, function* () {
            yield SdkLoadService.Ready;
            const settings = yield this.toSettings(env);
            const client = yield this.sdkClientFactory.createSdkClient(new register_sdk_service_JsTokenProvider(this.apiService), settings);
            yield this.loadFeatureFlags(client);
            return client;
        })), (0,external_rxjs_namespaceObject.shareReplay)({ refCount: true, bufferSize: 1 }));
    }
    registerClient$(userId) {
        return this.sdkClientOverrides.pipe((0,external_rxjs_namespaceObject.takeWhile)((clients) => clients[userId] !== register_sdk_service_UnsetClient, false), (0,external_rxjs_namespaceObject.map)((clients) => {
            if (clients[userId] === register_sdk_service_UnsetClient) {
                throw new Error("Encountered UnsetClient even though it should have been filtered out");
            }
            return clients[userId];
        }), (0,external_rxjs_namespaceObject.distinctUntilChanged)(), (0,external_rxjs_namespaceObject.switchMap)((clientOverride) => {
            if (clientOverride) {
                return (0,external_rxjs_namespaceObject.of)(clientOverride);
            }
            return this.internalClient$(userId);
        }), (0,external_rxjs_namespaceObject.takeWhile)((client) => client !== undefined, false), (0,external_rxjs_namespaceObject.throwIfEmpty)(() => new UserNotLoggedInError(userId)));
    }
    /**
     * This method is used to create a client for a specific user by using the existing state of the application.
     * This client is token-only and does not initialize any encryption keys.
     * @param userId The user id for which to create the client
     * @returns An observable that emits the client for the user
     */
    internalClient$(userId) {
        const cached = this.sdkClientCache.get(userId);
        if (cached !== undefined) {
            return cached;
        }
        const account$ = this.accountService.accounts$.pipe((0,external_rxjs_namespaceObject.map)((accounts) => accounts[userId]), (0,external_rxjs_namespaceObject.distinctUntilChanged)());
        const client$ = (0,external_rxjs_namespaceObject.combineLatest)([
            this.environmentService.getEnvironment$(userId),
            account$,
            SdkLoadService.Ready, // Makes sure we wait (once) for the SDK to be loaded
        ]).pipe(
        // switchMap is required to allow the clean-up logic to be executed when `combineLatest` emits a new value.
        (0,external_rxjs_namespaceObject.switchMap)(([env, account]) => {
            // Create our own observable to be able to implement clean-up logic
            return new external_rxjs_namespaceObject.Observable((subscriber) => {
                const createAndInitializeClient = () => register_sdk_service_awaiter(this, void 0, void 0, function* () {
                    if (env == null || account == null) {
                        return undefined;
                    }
                    const settings = yield this.toSettings(env);
                    const client = yield this.sdkClientFactory.createSdkClient(new register_sdk_service_JsTokenProvider(this.apiService, userId), settings);
                    // Initialize the client managed repositories.
                    yield initializeClientManagedState(userId, client.platform().state(), this.stateProvider);
                    yield this.loadFeatureFlags(client);
                    return client;
                });
                let client;
                createAndInitializeClient()
                    .then((c) => {
                    client = c === undefined ? undefined : new Rc(c);
                    subscriber.next(client);
                })
                    .catch((e) => {
                    subscriber.error(e);
                });
                return () => client === null || client === void 0 ? void 0 : client.markForDisposal();
            });
        }), (0,external_rxjs_namespaceObject.tap)({ finalize: () => this.sdkClientCache.delete(userId) }), (0,external_rxjs_namespaceObject.shareReplay)({ refCount: true, bufferSize: 1 }));
        this.sdkClientCache.set(userId, client$);
        return client$;
    }
    loadFeatureFlags(client) {
        return register_sdk_service_awaiter(this, void 0, void 0, function* () {
            var _a;
            const serverConfig = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.configService.serverConfig$);
            const featureFlagMap = new Map(Object.entries((_a = serverConfig === null || serverConfig === void 0 ? void 0 : serverConfig.featureStates) !== null && _a !== void 0 ? _a : {})
                .filter(([, value]) => typeof value === "boolean") // The SDK only supports boolean feature flags at this time
                .map(([key, value]) => [key, value]));
            yield client.platform().load_flags(featureFlagMap);
        });
    }
    toSettings(env) {
        return register_sdk_service_awaiter(this, void 0, void 0, function* () {
            var _a;
            return {
                apiUrl: env.getApiUrl(),
                identityUrl: env.getIdentityUrl(),
                deviceType: toSdkDevice(this.platformUtilsService.getDevice()),
                userAgent: (_a = this.userAgent) !== null && _a !== void 0 ? _a : navigator.userAgent,
                bitwardenClientVersion: yield this.platformUtilsService.getApplicationVersionNumber(),
            };
        });
    }
}

;// ../../libs/common/src/platform/services/storage-service.provider.ts


;// ../../libs/common/src/platform/services/user-auto-unlock-key.service.ts
var user_auto_unlock_key_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

// TODO: this is a half measure improvement which allows us to reduce some side effects today (keyService.getUserKey setting user key in memory if auto key exists)
// but ideally, in the future, we would be able to put this logic into the keyService
// after the vault timeout settings service is transitioned to state provider so that
// the getUserKey logic can simply go to the correct location based on the vault timeout settings
// similar to the TokenService (it would either go to secure storage for the auto user key or memory for the user key)
class UserAutoUnlockKeyService {
    constructor(keyService) {
        this.keyService = keyService;
    }
    /**
     * The presence of the user key in memory dictates whether the user's vault is locked or unlocked.
     * However, for users that have the auto unlock user key set, we need to set the user key in memory
     * on application bootstrap and on active account changes so that the user's vault loads unlocked.
     * @param userId - The user id to check for an auto user key.
     * @returns True if the auto user key is set successfully, false otherwise.
     */
    setUserKeyInMemoryIfAutoUserKeySet(userId) {
        return user_auto_unlock_key_service_awaiter(this, void 0, void 0, function* () {
            if (userId == null) {
                return false;
            }
            const autoUserKey = yield this.keyService.getUserKeyFromStorage(KeySuffixOptions.Auto, userId);
            if (autoUserKey == null) {
                return false;
            }
            yield this.keyService.setUserKey(autoUserKey, userId);
            return true;
        });
    }
}

;// ../../libs/common/src/admin-console/models/data/provider.data.ts
class ProviderData {
    constructor(response) {
        this.id = response.id;
        this.name = response.name;
        this.status = response.status;
        this.type = response.type;
        this.enabled = response.enabled;
        this.userId = response.userId;
        this.useEvents = response.useEvents;
        this.providerStatus = response.providerStatus;
        this.providerType = response.providerType;
    }
}

;// ../../libs/common/src/tools/send/models/data/send-file.data.ts
class SendFileData {
    constructor(data) {
        if (data == null) {
            return;
        }
        this.id = data.id;
        this.fileName = data.fileName;
        this.size = data.size;
        this.sizeName = data.sizeName;
    }
}

;// ../../libs/common/src/tools/send/models/data/send-text.data.ts
class SendTextData {
    constructor(data) {
        if (data == null) {
            return;
        }
        this.text = data.text;
        this.hidden = data.hidden;
    }
}

;// ../../libs/common/src/tools/send/models/data/send.data.ts



class SendData {
    constructor(response) {
        if (response == null) {
            return;
        }
        this.id = response.id;
        this.accessId = response.accessId;
        this.type = response.type;
        this.authType = response.authType;
        this.name = response.name;
        this.notes = response.notes;
        this.key = response.key;
        this.maxAccessCount = response.maxAccessCount;
        this.accessCount = response.accessCount;
        this.revisionDate = response.revisionDate;
        this.expirationDate = response.expirationDate;
        this.deletionDate = response.deletionDate;
        this.password = response.password;
        this.emails = response.emails;
        this.disabled = response.disable;
        this.hideEmail = response.hideEmail;
        this.authType = response.authType;
        switch (this.type) {
            case send_type_SendType.Text:
                this.text = new SendTextData(response.text);
                break;
            case send_type_SendType.File:
                this.file = new SendFileData(response.file);
                break;
            default:
                break;
        }
    }
}

;// ../../libs/common/src/vault/models/data/folder.data.ts
class FolderData {
    constructor(response) {
        var _a, _b, _c;
        this.name = (_a = response.name) !== null && _a !== void 0 ? _a : "";
        this.id = (_b = response.id) !== null && _b !== void 0 ? _b : "";
        this.revisionDate = (_c = response.revisionDate) !== null && _c !== void 0 ? _c : new Date().toISOString();
    }
    static fromJSON(obj) {
        if (obj == null) {
            return null;
        }
        return new FolderData({
            id: obj.id,
            name: obj.name,
            revisionDate: obj.revisionDate,
        });
    }
}

;// ../../libs/common/src/platform/sync/core-sync.service.ts
var core_sync_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore






const LAST_SYNC_DATE = new UserKeyDefinition(SYNC_DISK, "lastSync", {
    deserializer: (d) => (d != null ? new Date(d) : null),
    clearOn: ["logout"],
});
/**
 * Core SyncService Logic EXCEPT for fullSync so that implementations can differ.
 */
class CoreSyncService {
    constructor(tokenService, folderService, folderApiService, messageSender, logService, cipherService, collectionService, apiService, accountService, authService, sendService, sendApiService, stateProvider) {
        this.tokenService = tokenService;
        this.folderService = folderService;
        this.folderApiService = folderApiService;
        this.messageSender = messageSender;
        this.logService = logService;
        this.cipherService = cipherService;
        this.collectionService = collectionService;
        this.apiService = apiService;
        this.accountService = accountService;
        this.authService = authService;
        this.sendService = sendService;
        this.sendApiService = sendApiService;
        this.stateProvider = stateProvider;
        this.syncInProgress = false;
    }
    getLastSync() {
        return core_sync_service_awaiter(this, void 0, void 0, function* () {
            const userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.map)((a) => a === null || a === void 0 ? void 0 : a.id)));
            if (userId == null) {
                return null;
            }
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.lastSync$(userId));
        });
    }
    lastSync$(userId) {
        return this.stateProvider.getUser(userId, LAST_SYNC_DATE).state$;
    }
    activeUserLastSync$() {
        return this.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.switchMap)((a) => {
            if (a == null) {
                return (0,external_rxjs_namespaceObject.of)(null);
            }
            return this.lastSync$(a.id);
        }));
    }
    setLastSync(date, userId) {
        return core_sync_service_awaiter(this, void 0, void 0, function* () {
            yield this.stateProvider.getUser(userId, LAST_SYNC_DATE).update(() => date);
        });
    }
    syncUpsertFolder(notification, isEdit, userId) {
        return core_sync_service_awaiter(this, void 0, void 0, function* () {
            this.syncStarted();
            const authStatus = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.authService.authStatusFor$(userId));
            if (authStatus >= authentication_status_AuthenticationStatus.Locked) {
                try {
                    const localFolder = yield this.folderService.get(notification.id, userId);
                    if ((!isEdit && localFolder == null) ||
                        (isEdit && localFolder != null && localFolder.revisionDate < notification.revisionDate)) {
                        const remoteFolder = yield this.folderApiService.get(notification.id);
                        if (remoteFolder != null) {
                            yield this.folderService.upsert(new FolderData(remoteFolder), userId);
                            this.messageSender.send("syncedUpsertedFolder", { folderId: notification.id });
                            return this.syncCompleted(true, userId);
                        }
                    }
                }
                catch (e) {
                    this.logService.error(e);
                }
            }
            return this.syncCompleted(false, userId);
        });
    }
    syncDeleteFolder(notification, userId) {
        return core_sync_service_awaiter(this, void 0, void 0, function* () {
            this.syncStarted();
            const authStatus = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.authService.authStatusFor$(userId));
            if (authStatus >= authentication_status_AuthenticationStatus.Locked) {
                yield this.folderService.delete(notification.id, userId);
                this.messageSender.send("syncedDeletedFolder", { folderId: notification.id });
                this.syncCompleted(true, userId);
                return true;
            }
            return this.syncCompleted(false, userId);
        });
    }
    syncUpsertCipher(notification, isEdit, userId) {
        return core_sync_service_awaiter(this, void 0, void 0, function* () {
            this.syncStarted();
            const authStatus = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.authService.authStatusFor$(userId));
            if (authStatus >= authentication_status_AuthenticationStatus.Locked) {
                try {
                    let shouldUpdate = true;
                    const localCipher = yield this.cipherService.get(notification.id, userId);
                    if (localCipher != null && localCipher.revisionDate >= notification.revisionDate) {
                        shouldUpdate = false;
                    }
                    let checkCollections = false;
                    if (shouldUpdate) {
                        if (isEdit) {
                            shouldUpdate = localCipher != null;
                            checkCollections = true;
                        }
                        else {
                            if (notification.collectionIds == null || notification.organizationId == null) {
                                shouldUpdate = localCipher == null;
                            }
                            else {
                                shouldUpdate = false;
                                checkCollections = true;
                            }
                        }
                    }
                    if (!shouldUpdate &&
                        checkCollections &&
                        notification.organizationId != null &&
                        notification.collectionIds != null &&
                        notification.collectionIds.length > 0) {
                        const collections = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.collectionService
                            .encryptedCollections$(userId)
                            .pipe((0,external_rxjs_namespaceObject.map)((collections) => collections !== null && collections !== void 0 ? collections : [])));
                        if (collections != null) {
                            for (let i = 0; i < collections.length; i++) {
                                if (notification.collectionIds.indexOf(collections[i].id) > -1) {
                                    shouldUpdate = true;
                                    break;
                                }
                            }
                        }
                    }
                    if (shouldUpdate) {
                        const remoteCipher = yield this.apiService.getFullCipherDetails(notification.id);
                        if (remoteCipher != null) {
                            yield this.cipherService.upsert(new CipherData(remoteCipher));
                            this.messageSender.send("syncedUpsertedCipher", { cipherId: notification.id });
                            return this.syncCompleted(true, userId);
                        }
                    }
                }
                catch (e) {
                    if (e != null && e.statusCode === 404 && isEdit) {
                        yield this.cipherService.delete(notification.id, userId);
                        this.messageSender.send("syncedDeletedCipher", { cipherId: notification.id });
                        return this.syncCompleted(true, userId);
                    }
                }
            }
            return this.syncCompleted(false, userId);
        });
    }
    syncDeleteCipher(notification, userId) {
        return core_sync_service_awaiter(this, void 0, void 0, function* () {
            this.syncStarted();
            const authStatus = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.authService.authStatusFor$(userId));
            if (authStatus >= authentication_status_AuthenticationStatus.Locked) {
                yield this.cipherService.delete(notification.id, userId);
                this.messageSender.send("syncedDeletedCipher", { cipherId: notification.id });
                return this.syncCompleted(true, userId);
            }
            return this.syncCompleted(false, userId);
        });
    }
    syncUpsertSend(notification, isEdit) {
        return core_sync_service_awaiter(this, void 0, void 0, function* () {
            this.syncStarted();
            const [activeUserId, status] = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.switchMap)((a) => {
                if (a == null) {
                    (0,external_rxjs_namespaceObject.of)([null, authentication_status_AuthenticationStatus.LoggedOut]);
                }
                return this.authService.authStatusFor$(a.id).pipe((0,external_rxjs_namespaceObject.map)((s) => [a.id, s]));
            })));
            // Process only server notifications for currently active user when user is not logged out
            // TODO: once send service allows data manipulation of non-active users, this should process any received notification
            if (activeUserId === notification.userId && status !== authentication_status_AuthenticationStatus.LoggedOut) {
                try {
                    const localSend = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sendService.get$(notification.id));
                    if ((!isEdit && localSend == null) ||
                        (isEdit && localSend != null && localSend.revisionDate < notification.revisionDate)) {
                        const remoteSend = yield this.sendApiService.getSend(notification.id);
                        if (remoteSend != null) {
                            yield this.sendService.upsert(new SendData(remoteSend));
                            this.messageSender.send("syncedUpsertedSend", { sendId: notification.id });
                            return this.syncCompleted(true, activeUserId);
                        }
                    }
                }
                catch (e) {
                    this.logService.error(e);
                }
            }
            // TODO: Update syncCompleted userId when send service allows modification of non-active users
            return this.syncCompleted(false, undefined);
        });
    }
    syncDeleteSend(notification) {
        return core_sync_service_awaiter(this, void 0, void 0, function* () {
            this.syncStarted();
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.map)((a) => a === null || a === void 0 ? void 0 : a.id)));
            if (activeUserId != null &&
                (yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.tokenService.hasAccessToken$(activeUserId)))) {
                yield this.sendService.delete(notification.id);
                this.messageSender.send("syncedDeletedSend", { sendId: notification.id });
                // TODO: Update syncCompleted userId when send service allows modification of non-active users
                this.syncCompleted(true, undefined);
                return true;
            }
            return this.syncCompleted(false, undefined);
        });
    }
    // Helpers
    syncStarted() {
        this.syncInProgress = true;
        this.messageSender.send("syncStarted");
    }
    syncCompleted(successfully, userId) {
        this.syncInProgress = false;
        this.messageSender.send("syncCompleted", { successfully: successfully, userId });
        return successfully;
    }
}

;// ../../libs/common/src/platform/sync/default-sync.service.ts
var default_sync_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop.
// eslint-disable-next-line no-restricted-imports











class DefaultSyncService extends CoreSyncService {
    constructor(masterPasswordService, accountService, apiService, domainSettingsService, folderService, cipherService, keyService, collectionService, messageSender, policyService, sendService, logService, keyConnectorService, providerService, folderApiService, organizationService, sendApiService, userDecryptionOptionsService, avatarService, logoutCallback, billingAccountProfileStateService, tokenService, authService, stateProvider, securityStateService, kdfConfigService, accountCryptographicStateService) {
        super(tokenService, folderService, folderApiService, messageSender, logService, cipherService, collectionService, apiService, accountService, authService, sendService, sendApiService, stateProvider);
        this.masterPasswordService = masterPasswordService;
        this.domainSettingsService = domainSettingsService;
        this.keyService = keyService;
        this.policyService = policyService;
        this.keyConnectorService = keyConnectorService;
        this.providerService = providerService;
        this.organizationService = organizationService;
        this.userDecryptionOptionsService = userDecryptionOptionsService;
        this.avatarService = avatarService;
        this.logoutCallback = logoutCallback;
        this.billingAccountProfileStateService = billingAccountProfileStateService;
        this.securityStateService = securityStateService;
        this.kdfConfigService = kdfConfigService;
        this.accountCryptographicStateService = accountCryptographicStateService;
        this.syncInProgress = false;
        /** The promises associated with any in-flight api calls. */
        this.inFlightApiCalls = {
            refreshToken: null,
            sync: null,
        };
    }
    fullSync(forceSync, allowThrowOnErrorOrOptions) {
        return default_sync_service_awaiter(this, void 0, void 0, function* () {
            const { allowThrowOnError = false, skipTokenRefresh = false } = typeof allowThrowOnErrorOrOptions === "boolean"
                ? { allowThrowOnError: allowThrowOnErrorOrOptions }
                : (allowThrowOnErrorOrOptions !== null && allowThrowOnErrorOrOptions !== void 0 ? allowThrowOnErrorOrOptions : {});
            const userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.map)((a) => a === null || a === void 0 ? void 0 : a.id)));
            this.syncStarted();
            const authStatus = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.authService.authStatusFor$(userId));
            if (authStatus === authentication_status_AuthenticationStatus.LoggedOut) {
                return this.syncCompleted(false, userId);
            }
            const now = new Date();
            let needsSync = false;
            let needsSyncSucceeded = true;
            try {
                needsSync = yield this.needsSyncing(forceSync);
            }
            catch (e) {
                needsSyncSucceeded = false;
                if (allowThrowOnError) {
                    this.syncCompleted(false, userId);
                    throw e;
                }
            }
            if (!needsSync) {
                if (needsSyncSucceeded) {
                    yield this.setLastSync(now, userId);
                }
                return this.syncCompleted(false, userId);
            }
            try {
                if (!skipTokenRefresh) {
                    // Store the promise so multiple calls to refresh the token are not made
                    if (this.inFlightApiCalls.refreshToken === null) {
                        this.inFlightApiCalls.refreshToken = this.apiService.refreshIdentityToken();
                    }
                    yield this.inFlightApiCalls.refreshToken;
                }
                // Store the promise so multiple calls to sync are not made
                if (this.inFlightApiCalls.sync === null) {
                    this.inFlightApiCalls.sync = this.apiService.getSync();
                }
                else {
                    this.logService.debug("Sync: Sync network call already in progress, returning existing promise");
                }
                const response = yield this.inFlightApiCalls.sync;
                yield this.cipherService.clear(response.profile.id);
                yield this.syncUserDecryption(response.profile.id, response.userDecryption);
                yield this.syncProfile(response.profile);
                yield this.syncFolders(response.folders, response.profile.id);
                yield this.syncCollections(response.collections, response.profile.id);
                yield this.syncCiphers(response.ciphers, response.profile.id);
                yield this.syncSends(response.sends, response.profile.id);
                yield this.syncSettings(response.domains, response.profile.id);
                yield this.syncPolicies(response.policies, response.profile.id);
                yield this.setLastSync(now, userId);
                return this.syncCompleted(true, userId);
            }
            catch (e) {
                if (allowThrowOnError) {
                    this.syncCompleted(false, userId);
                    throw e;
                }
                else {
                    return this.syncCompleted(false, userId);
                }
            }
            finally {
                this.inFlightApiCalls.refreshToken = null;
                this.inFlightApiCalls.sync = null;
            }
        });
    }
    needsSyncing(forceSync) {
        return default_sync_service_awaiter(this, void 0, void 0, function* () {
            if (forceSync) {
                return true;
            }
            const lastSync = yield this.getLastSync();
            if (lastSync == null || lastSync.getTime() === 0) {
                return true;
            }
            const response = yield this.apiService.getAccountRevisionDate();
            if (response < 0 && this.logoutCallback) {
                // Account was deleted, log out now
                yield this.logoutCallback("accountDeleted");
            }
            if (new Date(response) <= lastSync) {
                return false;
            }
            return true;
        });
    }
    syncProfile(response) {
        return default_sync_service_awaiter(this, void 0, void 0, function* () {
            const stamp = yield this.tokenService.getSecurityStamp(response.id);
            if (stamp != null && stamp !== response.securityStamp) {
                if (this.logoutCallback != null) {
                    yield this.logoutCallback("invalidSecurityStamp");
                }
                throw new Error("Stamp has changed");
            }
            // Users with no master password will not have a key.
            if (response === null || response === void 0 ? void 0 : response.key) {
                yield this.masterPasswordService.setMasterKeyEncryptedUserKey(response.key, response.id);
            }
            // Cleanup: Only the first branch should be kept after the server always returns accountKeys https://bitwarden.atlassian.net/browse/PM-21768
            if (response.accountKeys != null) {
                yield this.accountCryptographicStateService.setAccountCryptographicState(response.accountKeys.toWrappedAccountCryptographicState(), response.id);
            }
            else {
                yield this.accountCryptographicStateService.setAccountCryptographicState({
                    V1: {
                        private_key: response.privateKey,
                    },
                }, response.id);
            }
            yield this.keyService.setProviderKeys(response.providers, response.id);
            yield this.keyService.setOrgKeys(response.organizations, response.providerOrganizations, response.id);
            yield this.avatarService.setSyncAvatarColor(response.id, response.avatarColor);
            yield this.tokenService.setSecurityStamp(response.securityStamp, response.id);
            yield this.accountService.setAccountEmailVerified(response.id, response.emailVerified);
            yield this.accountService.setAccountCreationDate(response.id, new Date(response.creationDate));
            yield this.accountService.setAccountVerifyNewDeviceLogin(response.id, response.verifyDevices);
            yield this.billingAccountProfileStateService.setHasPremium(response.premiumPersonally, response.premiumFromOrganization, response.id);
            yield this.keyConnectorService.setUsesKeyConnector(response.usesKeyConnector, response.id);
            yield this.setForceSetPasswordReasonIfNeeded(response);
            const providers = {};
            response.providers.forEach((p) => {
                providers[p.id] = new ProviderData(p);
            });
            yield this.providerService.save(providers, response.id);
            yield this.syncProfileOrganizations(response, response.id);
            if (yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyConnectorService.convertAccountRequired$)) {
                this.messageSender.send("convertAccountToKeyConnector");
            }
        });
    }
    setForceSetPasswordReasonIfNeeded(profileResponse) {
        return default_sync_service_awaiter(this, void 0, void 0, function* () {
            var _a;
            // The `forcePasswordReset` flag indicates an admin has reset the user's password and must be updated
            if (profileResponse.forcePasswordReset) {
                yield this.masterPasswordService.setForceSetPasswordReason(ForceSetPasswordReason.AdminForcePasswordReset, profileResponse.id);
            }
            const userDecryptionOptions = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.userDecryptionOptionsService.userDecryptionOptionsById$(profileResponse.id));
            if (userDecryptionOptions === null || userDecryptionOptions === undefined) {
                this.logService.error("Sync: Account decryption options are null or undefined.");
            }
            // Even though TDE users should only be in a single org (per single org policy), check
            // through all orgs for the manageResetPassword permission. If they have it in any org,
            // they should be forced to set a password.
            let hasManageResetPasswordPermission = false;
            for (const org of profileResponse.organizations) {
                const isAdmin = org.type === organization_user_type_enum_OrganizationUserType.Admin;
                const isOwner = org.type === organization_user_type_enum_OrganizationUserType.Owner;
                // Note: apparently permissions only come down populated for custom roles.
                if (isAdmin || isOwner || (org.permissions && org.permissions.manageResetPassword)) {
                    hasManageResetPasswordPermission = true;
                    break;
                }
            }
            if (userDecryptionOptions.trustedDeviceOption !== undefined &&
                !userDecryptionOptions.hasMasterPassword &&
                hasManageResetPasswordPermission) {
                // TDE user w/out MP went from having no password reset permission to having it.
                // Must set the force password reset reason so the auth guard will redirect to the set password page.
                const userId = (_a = (yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$))) === null || _a === void 0 ? void 0 : _a.id;
                yield this.masterPasswordService.setForceSetPasswordReason(ForceSetPasswordReason.TdeUserWithoutPasswordHasPasswordResetPermission, userId);
            }
        });
    }
    syncProfileOrganizations(response, userId) {
        return default_sync_service_awaiter(this, void 0, void 0, function* () {
            const organizations = {};
            response.organizations.forEach((o) => {
                organizations[o.id] = new OrganizationData(o, {
                    isMember: true,
                    isProviderUser: false,
                });
            });
            response.providerOrganizations.forEach((o) => {
                if (organizations[o.id] == null) {
                    organizations[o.id] = new OrganizationData(o, {
                        isMember: false,
                        isProviderUser: true,
                    });
                }
                else {
                    organizations[o.id].isProviderUser = true;
                }
            });
            yield this.organizationService.replace(organizations, userId);
        });
    }
    syncFolders(response, userId) {
        return default_sync_service_awaiter(this, void 0, void 0, function* () {
            const folders = {};
            response.forEach((f) => {
                folders[f.id] = new FolderData(f);
            });
            return yield this.folderService.replace(folders, userId);
        });
    }
    syncCollections(response, userId) {
        return default_sync_service_awaiter(this, void 0, void 0, function* () {
            const collections = {};
            response.forEach((c) => {
                collections[c.id] = new collection_data_CollectionData(c);
            });
            return yield this.collectionService.replace(collections, userId);
        });
    }
    syncCiphers(response, userId) {
        return default_sync_service_awaiter(this, void 0, void 0, function* () {
            const ciphers = {};
            response.forEach((c) => {
                ciphers[c.id] = new CipherData(c);
            });
            return yield this.cipherService.replace(ciphers, userId);
        });
    }
    syncSends(response, userId) {
        return default_sync_service_awaiter(this, void 0, void 0, function* () {
            const sends = {};
            response.forEach((s) => {
                sends[s.id] = new SendData(s);
            });
            return yield this.sendService.replace(sends, userId);
        });
    }
    syncSettings(response, userId) {
        return default_sync_service_awaiter(this, void 0, void 0, function* () {
            let eqDomains = [];
            if (response != null && response.equivalentDomains != null) {
                eqDomains = eqDomains.concat(response.equivalentDomains);
            }
            if (response != null && response.globalEquivalentDomains != null) {
                response.globalEquivalentDomains.forEach((global) => {
                    if (global.domains.length > 0) {
                        eqDomains.push(global.domains);
                    }
                });
            }
            return this.domainSettingsService.setEquivalentDomains(eqDomains, userId);
        });
    }
    syncPolicies(response, userId) {
        return default_sync_service_awaiter(this, void 0, void 0, function* () {
            const policies = {};
            if (response != null) {
                response.forEach((p) => {
                    policies[p.id] = new PolicyData(p);
                });
            }
            return yield this.policyService.replace(policies, userId);
        });
    }
    syncUserDecryption(userId, userDecryption) {
        return default_sync_service_awaiter(this, void 0, void 0, function* () {
            if (userDecryption == null) {
                return;
            }
            if (userDecryption.masterPasswordUnlock != null) {
                const masterPasswordUnlockData = userDecryption.masterPasswordUnlock.toMasterPasswordUnlockData();
                yield this.masterPasswordService.setMasterPasswordUnlockData(masterPasswordUnlockData, userId);
                yield this.kdfConfigService.setKdfConfig(userId, masterPasswordUnlockData.kdf);
            }
            // Update WebAuthn PRF options if present
            if (userDecryption.webAuthnPrfOptions != null && userDecryption.webAuthnPrfOptions.length > 0) {
                try {
                    // Only update if this is the active user, since setUserDecryptionOptions()
                    // operates on the active user's state
                    const activeAccount = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$);
                    if ((activeAccount === null || activeAccount === void 0 ? void 0 : activeAccount.id) !== userId) {
                        return;
                    }
                    // Get current options without blocking if they don't exist yet
                    const currentUserDecryptionOptions = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.userDecryptionOptionsService.userDecryptionOptionsById$(userId)).catch(() => {
                        return null;
                    });
                    if (currentUserDecryptionOptions != null) {
                        // Update the PRF options while preserving other decryption options
                        const updatedOptions = Object.assign(new UserDecryptionOptions(), currentUserDecryptionOptions);
                        updatedOptions.webAuthnPrfOptions = userDecryption.webAuthnPrfOptions
                            .map((option) => WebAuthnPrfUserDecryptionOption.fromResponse(option))
                            .filter((option) => option !== undefined);
                        yield this.userDecryptionOptionsService.setUserDecryptionOptionsById(activeAccount.id, updatedOptions);
                    }
                }
                catch (error) {
                    this.logService.error("[Sync] Failed to update WebAuthn PRF options:", error);
                }
            }
        });
    }
}

;// ../../libs/common/src/platform/sync/internal.ts



;// external "rxjs/operators"
const operators_namespaceObject = require("rxjs/operators");
;// ../../libs/common/src/services/audit.service.ts
var audit_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};



const PwnedPasswordsApi = "https://api.pwnedpasswords.com/range/";
class AuditService {
    constructor(cryptoFunctionService, apiService, hibpApiService, maxConcurrent = 100) {
        this.cryptoFunctionService = cryptoFunctionService;
        this.apiService = apiService;
        this.hibpApiService = hibpApiService;
        this.maxConcurrent = maxConcurrent;
        this.passwordLeakedSubject = new external_rxjs_namespaceObject.Subject();
        this.maxConcurrent = maxConcurrent;
        this.passwordLeakedSubject
            .pipe((0,operators_namespaceObject.mergeMap)(
        // Handle each password leak request, resolving or rejecting the associated promise.
        (req) => audit_service_awaiter(this, void 0, void 0, function* () {
            try {
                const count = yield this.fetchLeakedPasswordCount(req.password);
                req.resolve(count);
            }
            catch (err) {
                req.reject(err);
            }
        }), this.maxConcurrent))
            .subscribe();
    }
    passwordLeaked(password) {
        return audit_service_awaiter(this, void 0, void 0, function* () {
            return new Promise((resolve, reject) => {
                this.passwordLeakedSubject.next({ password, resolve, reject });
            });
        });
    }
    /**
     * Fetches the count of leaked passwords from the Pwned Passwords API.
     * @param password The password to check.
     * @returns A promise that resolves to the number of times the password has been leaked.
     */
    fetchLeakedPasswordCount(password) {
        return audit_service_awaiter(this, void 0, void 0, function* () {
            const hashBytes = yield this.cryptoFunctionService.hash(password, "sha1");
            const hash = utils_Utils.fromArrayToHex(hashBytes).toUpperCase();
            const hashStart = hash.substr(0, 5);
            const hashEnding = hash.substr(5);
            const response = yield this.apiService.nativeFetch(new Request(PwnedPasswordsApi + hashStart));
            const leakedHashes = yield response.text();
            const match = leakedHashes.split(/\r?\n/).find((v) => {
                return v.split(":")[0] === hashEnding;
            });
            return match != null ? parseInt(match.split(":")[1], 10) : 0;
        });
    }
    breachedAccounts(username) {
        return audit_service_awaiter(this, void 0, void 0, function* () {
            return this.hibpApiService.getHibpBreach(username);
        });
    }
}

;// ../../libs/common/src/tools/cryptography/organization-encryptor.abstraction.ts
/** An encryption strategy that protects a type's secrets with
 *  organization-specific keys. This strategy is bound to a specific organization.
 */
class OrganizationEncryptor {
}

;// ../../libs/common/src/tools/cryptography/organization-key-encryptor.ts
var organization_key_encryptor_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

/** A classification strategy that protects a type's secrets by encrypting them
 *  with an `OrgKey`
 */
class OrganizationKeyEncryptor extends OrganizationEncryptor {
    /** Instantiates the encryptor
     *  @param organizationId identifies the organization bound to the encryptor.
     *  @param encryptService protects properties of `Secret`.
     *  @param key the key instance protecting the data.
     *  @param dataPacker packs and unpacks data classified as secrets.
     */
    constructor(organizationId, encryptService, key, dataPacker) {
        super();
        this.organizationId = organizationId;
        this.encryptService = encryptService;
        this.key = key;
        this.dataPacker = dataPacker;
        this.assertHasValue("organizationId", organizationId);
        this.assertHasValue("key", key);
        this.assertHasValue("dataPacker", dataPacker);
        this.assertHasValue("encryptService", encryptService);
    }
    encrypt(secret) {
        return organization_key_encryptor_awaiter(this, void 0, void 0, function* () {
            this.assertHasValue("secret", secret);
            let packed = this.dataPacker.pack(secret);
            const encrypted = yield this.encryptService.encryptString(packed, this.key);
            packed = null;
            return encrypted;
        });
    }
    decrypt(secret) {
        return organization_key_encryptor_awaiter(this, void 0, void 0, function* () {
            this.assertHasValue("secret", secret);
            let decrypted = yield this.encryptService.decryptString(secret, this.key);
            const unpacked = this.dataPacker.unpack(decrypted);
            decrypted = null;
            return unpacked;
        });
    }
    assertHasValue(name, value) {
        if (value === undefined || value === null) {
            throw new Error(`${name} cannot be null or undefined`);
        }
    }
}

;// ../../libs/common/src/tools/cryptography/key-service-legacy-encryptor-provider.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore





/** Creates encryptors
 */
class KeyServiceLegacyEncryptorProvider {
    /** Instantiates the legacy encryptor provider.
     *  @param encryptService injected into encryptors to perform encryption
     *  @param keyService looks up keys for construction into an encryptor
     */
    constructor(encryptService, keyService) {
        this.encryptService = encryptService;
        this.keyService = keyService;
    }
    userEncryptor$(frameSize, dependencies) {
        const packer = new PaddedDataPacker(frameSize);
        const encryptor$ = dependencies.singleUserId$.pipe(errorOnChange((userId) => userId, (expectedUserId, actualUserId) => ({ expectedUserId, actualUserId })), (0,external_rxjs_namespaceObject.connect)((singleUserId$) => {
            const singleUserId = new external_rxjs_namespaceObject.ReplaySubject(1);
            singleUserId$.subscribe(singleUserId);
            return singleUserId.pipe((0,external_rxjs_namespaceObject.switchMap)((userId) => this.keyService.userKey$(userId).pipe(
            // wait until the key becomes available
            (0,external_rxjs_namespaceObject.skipWhile)((key) => !key), 
            // complete when the key becomes unavailable
            (0,external_rxjs_namespaceObject.takeWhile)((key) => !!key), (0,external_rxjs_namespaceObject.map)((key) => {
                const encryptor = new UserKeyEncryptor(userId, this.encryptService, key, packer);
                return { userId, encryptor };
            }), (0,external_rxjs_namespaceObject.materialize)())), (0,external_rxjs_namespaceObject.dematerialize)(), (0,external_rxjs_namespaceObject.takeUntil)(rx_anyComplete(singleUserId)));
        }));
        return encryptor$;
    }
    organizationEncryptor$(frameSize, dependencies) {
        const packer = new PaddedDataPacker(frameSize);
        const encryptor$ = dependencies.singleOrganizationId$.pipe(errorOnChange((pair) => pair.userId, (expectedUserId, actualUserId) => ({ expectedUserId, actualUserId })), errorOnChange((pair) => pair.organizationId, (expectedOrganizationId, actualOrganizationId) => ({
            expectedOrganizationId,
            actualOrganizationId,
        })), (0,external_rxjs_namespaceObject.connect)((singleOrganizationId$) => {
            const singleOrganizationId = new external_rxjs_namespaceObject.ReplaySubject(1);
            singleOrganizationId$.subscribe(singleOrganizationId);
            return singleOrganizationId.pipe((0,external_rxjs_namespaceObject.switchMap)((pair) => this.keyService.orgKeys$(pair.userId).pipe(
            // wait until the key becomes available
            (0,external_rxjs_namespaceObject.skipWhile)((keys) => !keys), 
            // complete when the key becomes unavailable
            (0,external_rxjs_namespaceObject.takeWhile)((keys) => !!keys), (0,external_rxjs_namespaceObject.map)((keys) => {
                const organizationId = pair.organizationId;
                const key = keys[organizationId];
                const encryptor = new OrganizationKeyEncryptor(organizationId, this.encryptService, key, packer);
                return { organizationId, encryptor };
            }), (0,external_rxjs_namespaceObject.materialize)())), (0,external_rxjs_namespaceObject.dematerialize)(), (0,external_rxjs_namespaceObject.takeUntil)(rx_anyComplete(singleOrganizationId)));
        }));
        return encryptor$;
    }
}

;// ../../libs/common/src/tools/extension/data.ts
/** well-known name for a feature extensible through an extension. */
const Site = Object.freeze({
    forwarder: "forwarder",
});
/** well-known name for a field surfaced from an extension site to a vendor. */
const data_Field = Object.freeze({
    token: "token",
    baseUrl: "baseUrl",
    domain: "domain",
    prefix: "prefix",
});
/** Permission levels for metadata. */
const Permission = Object.freeze({
    /** unless a rule denies access, allow it. If a permission is `null`
     * or `undefined` it should be treated as `Permission.default`.
     */
    default: "default",
    /** unless a rule allows access, deny it. */
    none: "none",
    /** access is explicitly granted to use an extension. */
    allow: "allow",
    /** access is explicitly prohibited for this extension. This rule overrides allow rules. */
    deny: "deny",
});

;// ../../libs/common/src/tools/extension/metadata.ts

const DefaultSites = Object.freeze(Object.keys(Site));
const DefaultFields = Object.freeze(Object.keys(data_Field));
const Extension = {
    [Site.forwarder]: {
        id: Site.forwarder,
        availableFields: [data_Field.baseUrl, data_Field.domain, data_Field.prefix, data_Field.token],
    },
};
const AllowedPermissions = Object.freeze(Object.values(Permission));

;// ../../libs/common/src/tools/extension/extension-site.ts

/** Describes the capabilities of an extension site.
 *  This type is immutable.
 */
class ExtensionSite {
    /** instantiate the extension site
     *  @param site describes the extension site
     *  @param vendors describes the available vendors
     *  @param extensions describes the available extensions
     */
    constructor(site, extensions) {
        this.site = site;
        this.extensions = extensions;
        deepFreeze(this);
    }
}

;// ../../libs/common/src/tools/extension/runtime-extension-registry.ts



/** Tracks extension sites and the vendors that extend them in application memory. */
class RuntimeExtensionRegistry {
    /** Instantiates the extension registry
     *  @param allowedSites sites that are valid for use by any extension;
     *    this is most useful to disable an extension site that is only
     *    available on a specific client.
     *  @param allowedFields fields that are valid for use by any extension;
     *    this is most useful to prohibit access to a field via policy.
     */
    constructor(allowedSites, allowedFields) {
        this.allowedSites = allowedSites;
        this.allowedFields = allowedFields;
        this.allPermission = "default";
        this.siteRegistrations = new Map();
        this.sitePermissions = new Map();
        this.vendorRegistrations = new Map();
        this.vendorPermissions = new Map();
        this.extensionRegistrations = new Array();
        this.extensionsBySiteByVendor = new Map();
        Object.freeze(this.allowedFields);
        Object.freeze(this.allowedSites);
    }
    registerSite(site) {
        if (!this.allowedSites.includes(site.id)) {
            return this;
        }
        // verify requested fields are on the list of valid fields to expose to
        // an extension
        const availableFields = site.availableFields.filter((field) => this.allowedFields.includes(field));
        const validated = deepFreeze({ id: site.id, availableFields });
        if (!this.siteRegistrations.has(site.id)) {
            this.siteRegistrations.set(site.id, validated);
        }
        return this;
    }
    site(site) {
        const result = this.siteRegistrations.get(site);
        return result;
    }
    sites() {
        const sites = [];
        for (const [k, site] of this.siteRegistrations.entries()) {
            const s = { site };
            const permission = this.sitePermissions.get(k);
            if (permission) {
                s.permission = permission;
            }
            sites.push(s);
        }
        return sites;
    }
    registerVendor(vendor) {
        if (!this.vendorRegistrations.has(vendor.id)) {
            const frozen = deepFreeze(vendor);
            this.vendorRegistrations.set(vendor.id, frozen);
        }
        return this;
    }
    vendor(vendor) {
        const result = this.vendorRegistrations.get(vendor);
        return result;
    }
    vendors() {
        const vendors = [];
        for (const [k, vendor] of this.vendorRegistrations.entries()) {
            const s = { vendor };
            const permission = this.vendorPermissions.get(k);
            if (permission) {
                s.permission = permission;
            }
            vendors.push(s);
        }
        return vendors;
    }
    setPermission(set, permission) {
        if (!AllowedPermissions.includes(permission)) {
            throw new Error(`invalid extension permission: ${permission}`);
        }
        if ("all" in set && set.all) {
            this.allPermission = permission;
        }
        else if ("vendor" in set) {
            this.vendorPermissions.set(set.vendor, permission);
        }
        else if ("site" in set) {
            if (this.allowedSites.includes(set.site)) {
                this.sitePermissions.set(set.site, permission);
            }
        }
        else {
            throw new Error(`Unrecognized extension set received: ${JSON.stringify(set)}.`);
        }
        return this;
    }
    permission(set) {
        if ("all" in set && set.all) {
            return this.allPermission;
        }
        else if ("vendor" in set) {
            return this.vendorPermissions.get(set.vendor);
        }
        else if ("site" in set) {
            return this.sitePermissions.get(set.site);
        }
        else {
            return undefined;
        }
    }
    permissions() {
        const rules = [];
        rules.push({ set: { all: true }, permission: this.allPermission });
        for (const [site, permission] of this.sitePermissions.entries()) {
            rules.push({ set: { site }, permission });
        }
        for (const [vendor, permission] of this.vendorPermissions.entries()) {
            rules.push({ set: { vendor }, permission });
        }
        return rules;
    }
    registerExtension(meta) {
        var _a;
        const site = this.siteRegistrations.get(meta.site.id);
        const vendor = this.vendorRegistrations.get(meta.product.vendor.id);
        if (!site || !vendor) {
            return this;
        }
        // exit early if the extension is already registered
        const extensionsByVendor = (_a = this.extensionsBySiteByVendor.get(meta.site.id)) !== null && _a !== void 0 ? _a : new Map();
        if (extensionsByVendor.has(meta.product.vendor.id)) {
            return this;
        }
        // create immutable copy; this updates the vendor and site with
        // their internalized representation to provide reference equality
        // across registrations
        const product = { vendor };
        if (meta.product.name) {
            product.name = meta.product.name;
        }
        const extension = Object.freeze({
            site,
            product: Object.freeze(product),
            host: Object.freeze(Object.assign({}, meta.host)),
            requestedFields: Object.freeze([...meta.requestedFields]),
        });
        // register it
        const index = this.extensionRegistrations.push(extension) - 1;
        extensionsByVendor.set(vendor.id, index);
        this.extensionsBySiteByVendor.set(site.id, extensionsByVendor);
        return this;
    }
    extension(site, vendor) {
        var _a, _b;
        const index = (_b = (_a = this.extensionsBySiteByVendor.get(site)) === null || _a === void 0 ? void 0 : _a.get(vendor)) !== null && _b !== void 0 ? _b : -1;
        if (index < 0) {
            return undefined;
        }
        else {
            return this.extensionRegistrations[index];
        }
    }
    getPermissions(site, vendor) {
        const permissions = [
            this.sitePermissions.get(site),
            this.vendorPermissions.get(vendor),
            this.allPermission,
            // Need to cast away `undefined` because typescript isn't
            // aware that the filter eliminates undefined elements
        ].filter((p) => !!p);
        return permissions;
    }
    extensions() {
        const extensions = [];
        for (const extension of this.extensionRegistrations) {
            const permissions = this.getPermissions(extension.site.id, extension.product.vendor.id);
            extensions.push({ extension, permissions });
        }
        return extensions;
    }
    build(id) {
        var _a, _b;
        const site = this.siteRegistrations.get(id);
        if (!site) {
            return undefined;
        }
        if (this.allPermission === "deny") {
            return new ExtensionSite(site, new Map());
        }
        const extensions = new Map();
        const entries = (_b = (_a = this.extensionsBySiteByVendor.get(id)) === null || _a === void 0 ? void 0 : _a.entries()) !== null && _b !== void 0 ? _b : [];
        for (const [vendor, index] of entries) {
            const permissions = this.getPermissions(id, vendor);
            const extension = evaluate(permissions, this.extensionRegistrations[index]);
            if (extension) {
                extensions.set(vendor, extension);
            }
        }
        const extensionSite = new ExtensionSite(site, extensions);
        return extensionSite;
    }
}
function evaluate(permissions, value) {
    // deny always wins
    if (permissions.includes("deny")) {
        return undefined;
    }
    // allow overrides implicit permissions
    if (permissions.includes("allow")) {
        return value;
    }
    // none permission becomes a deny
    if (permissions.includes("none")) {
        return undefined;
    }
    // default permission becomes an allow
    if (permissions.includes("default")) {
        return value;
    }
    // if no permission is recognized, throw. This code is unreachable.
    throw new Error("failed to recognize any permissions");
}

;// ../../libs/common/src/tools/extension/vendor/addyio.ts



const addyio_AddyIo = {
    id: data_Vendor.addyio,
    name: "Addy.io",
};
const AddyIoExtensions = [
    {
        site: Extension.forwarder,
        product: {
            vendor: addyio_AddyIo,
        },
        host: {
            authorization: "bearer",
            selfHost: "maybe",
            baseUrl: "https://app.addy.io",
        },
        requestedFields: [data_Field.token, data_Field.baseUrl, data_Field.domain],
    },
];

;// ../../libs/common/src/tools/extension/vendor/bitwarden.ts

const Bitwarden = Object.freeze({
    id: data_Vendor.bitwarden,
    name: "Bitwarden",
});

;// ../../libs/common/src/tools/extension/vendor/duckduckgo.ts



const duckduckgo_DuckDuckGo = {
    id: data_Vendor.duckduckgo,
    name: "DuckDuckGo",
};
const DuckDuckGoExtensions = [
    {
        site: Extension.forwarder,
        product: {
            vendor: duckduckgo_DuckDuckGo,
        },
        host: {
            authorization: "bearer",
            selfHost: "never",
            baseUrl: "https://quack.duckduckgo.com/api",
        },
        requestedFields: [data_Field.token],
    },
];

;// ../../libs/common/src/tools/extension/vendor/fastmail.ts



const fastmail_Fastmail = {
    id: data_Vendor.fastmail,
    name: "Fastmail",
};
const FastmailExtensions = [
    {
        site: Extension.forwarder,
        product: {
            vendor: fastmail_Fastmail,
        },
        host: {
            authorization: "bearer",
            selfHost: "maybe",
            baseUrl: "https://api.fastmail.com",
        },
        requestedFields: [data_Field.token],
    },
];

;// ../../libs/common/src/tools/extension/vendor/forwardemail.ts



const forwardemail_ForwardEmail = {
    id: data_Vendor.forwardemail,
    name: "Forward Email",
};
const ForwardEmailExtensions = [
    {
        site: Extension.forwarder,
        product: {
            vendor: forwardemail_ForwardEmail,
        },
        host: {
            authorization: "basic-username",
            selfHost: "never",
            baseUrl: "https://api.forwardemail.net",
        },
        requestedFields: [data_Field.domain, data_Field.token],
    },
];

;// ../../libs/common/src/tools/extension/vendor/mozilla.ts



const Mozilla = {
    id: data_Vendor.mozilla,
    name: "Mozilla",
};
const MozillaExtensions = [
    {
        site: Extension.forwarder,
        product: {
            vendor: Mozilla,
            name: "Firefox Relay",
        },
        host: {
            authorization: "token",
            selfHost: "never",
            baseUrl: "https://relay.firefox.com/api",
        },
        requestedFields: [data_Field.token],
    },
];

;// ../../libs/common/src/tools/extension/vendor/simplelogin.ts



const simplelogin_SimpleLogin = {
    id: data_Vendor.simplelogin,
    name: "SimpleLogin",
};
const SimpleLoginExtensions = [
    {
        site: Extension.forwarder,
        product: {
            vendor: simplelogin_SimpleLogin,
        },
        host: {
            authentication: true,
            selfHost: "maybe",
            baseUrl: "https://app.simplelogin.io",
        },
        requestedFields: [data_Field.baseUrl, data_Field.token, data_Field.domain],
    },
];

;// ../../libs/common/src/tools/extension/vendor/index.ts








const Vendors = deepFreeze([
    addyio_AddyIo,
    Bitwarden,
    duckduckgo_DuckDuckGo,
    fastmail_Fastmail,
    forwardemail_ForwardEmail,
    Mozilla,
    simplelogin_SimpleLogin,
]);
const VendorExtensions = deepFreeze([
    AddyIoExtensions,
    DuckDuckGoExtensions,
    FastmailExtensions,
    ForwardEmailExtensions,
    MozillaExtensions,
    SimpleLoginExtensions,
].flat());

;// ../../libs/common/src/tools/extension/factory.ts



// FIXME: find a better way to build the registry than a hard-coded factory function
/** Constructs the extension registry */
function buildExtensionRegistry() {
    const registry = new RuntimeExtensionRegistry(DefaultSites, DefaultFields);
    for (const site of Reflect.ownKeys(Extension)) {
        registry.registerSite(Extension[site]);
    }
    for (const vendor of Vendors) {
        registry.registerVendor(vendor);
    }
    for (const extension of VendorExtensions) {
        registry.registerExtension(extension);
    }
    return registry;
}

;// external "zxcvbn"
const external_zxcvbn_namespaceObject = require("zxcvbn");
var external_zxcvbn_default = /*#__PURE__*/__webpack_require__.n(external_zxcvbn_namespaceObject);
;// ../../libs/common/src/tools/password-strength/password-strength.service.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

class PasswordStrengthService {
    /**
     * Calculates a password strength score using zxcvbn.
     * @param password The password to calculate the strength of.
     * @param emailInput An unparsed email address to use as user input.
     * @param userInputs An array of additional user inputs to use when calculating the strength.
     */
    getPasswordStrength(password, emailInput = null, userInputs = null) {
        if (password == null || password.length === 0) {
            return null;
        }
        const globalUserInputs = [
            "bitwarden",
            "bit",
            "warden",
            ...(userInputs !== null && userInputs !== void 0 ? userInputs : []),
            ...this.emailToUserInputs(emailInput),
        ];
        // Use a hash set to get rid of any duplicate user inputs
        const finalUserInputs = Array.from(new Set(globalUserInputs));
        const result = external_zxcvbn_default()(password, finalUserInputs);
        return result;
    }
    /**
     * Convert an email address into a list of user inputs for zxcvbn by
     * taking the local part of the email address and splitting it into words.
     * @param email
     * @private
     */
    emailToUserInputs(email) {
        if (email == null || email.length === 0) {
            return [];
        }
        const atPosition = email.indexOf("@");
        if (atPosition < 0) {
            return [];
        }
        return email
            .substring(0, atPosition)
            .trim()
            .toLowerCase()
            .split(/[^A-Za-z0-9]/);
    }
}

;// ../../libs/common/src/tools/password-strength/index.ts



;// ../../libs/common/src/tools/extension/util.ts


/** Create an object key from an extension instance and a site profile.
 *  @param profile the extension profile to bind
 *  @param extension the extension metadata to bind
 */
function toObjectKey(profile, extension) {
    // FIXME: eliminate this cast
    const classifier = new PrivateClassifier();
    const result = Object.assign(Object.assign({}, profile.storage), { 
        // fields controlled by the extension system override those in the profile
        target: "object", key: `${extension.site.id}.${extension.product.vendor.id}.${profile.storage.key}`, state: EXTENSION_DISK, classifier, format: "classified" });
    return result;
}

;// ../../libs/common/src/tools/extension/extension.service.ts



/** Provides configuration and storage support for Bitwarden client extensions.
 *  These extensions integrate 3rd party services into Bitwarden.
 */
class ExtensionService {
    /** Instantiate the extension service.
     *  @param registry provides runtime status for extension sites
     *  @param providers provide persistent data
     */
    constructor(registry, providers) {
        this.registry = registry;
        this.providers = providers;
        this.log = providers.log({
            type: "ExtensionService",
        });
    }
    /** Get a subject bound to a user's extension settings
     * @param profile the site's extension profile
     * @param vendor the vendor integrated at the extension site
     * @param dependencies.account$ the account to which the settings are bound
     * @returns a subject bound to the requested user's generator settings
     */
    settings(profile, vendor, dependencies) {
        const metadata = this.registry.extension(profile.site, vendor);
        if (!metadata) {
            this.log.panic({ site: profile.site, vendor }, "extension not defined");
        }
        const key = toObjectKey(profile, metadata);
        const account$ = dependencies.account$.pipe((0,external_rxjs_namespaceObject.shareReplay)({ bufferSize: 1, refCount: true }));
        // FIXME: load and apply constraints
        const subject = new user_state_subject_UserStateSubject(key, this.providers, { account$ });
        return subject;
    }
    /** Look up extension metadata for a site
     *  @param site defines the site to retrieve.
     *  @returns the extensions available at the site.
     */
    site(site) {
        return this.registry.build(site);
    }
}

;// ../../libs/common/src/tools/log/default-semantic-logger.ts

/** Sends semantic logs to the console.
 *  @remarks the behavior of this logger is based on `LogService`; it
 *   replaces dynamic messages (`%s`) with a JSON-formatted semantic log.
 */
class default_semantic_logger_DefaultSemanticLogger {
    /** Instantiates a console semantic logger
     *  @param context a static payload that is cloned when the logger
     *   logs a message. The `messages`, `level`, and `content` fields
     *   are reserved for use by loggers.
     */
    constructor(logger, context, now = () => Date.now()) {
        this.logger = logger;
        this.now = now;
        this.context = context && typeof context === "object" ? context : {};
    }
    debug(content, message) {
        this.log(content, LogLevel.Debug, message);
    }
    info(content, message) {
        this.log(content, LogLevel.Info, message);
    }
    warn(content, message) {
        this.log(content, LogLevel.Warning, message);
    }
    error(content, message) {
        this.log(content, LogLevel.Error, message);
    }
    panic(content, message) {
        this.log(content, LogLevel.Error, message);
        const panicMessage = message !== null && message !== void 0 ? message : (typeof content === "string" ? content : "a fatal error occurred");
        throw new Error(panicMessage);
    }
    log(content, level, message) {
        const log = Object.assign(Object.assign({}, this.context), { message, content: content !== null && content !== void 0 ? content : undefined, level: stringifyLevel(level), "@timestamp": this.now() });
        if (typeof content === "string" && !message) {
            log.message = content;
            delete log.content;
        }
        this.logger.write(level, log);
    }
}
function stringifyLevel(level) {
    switch (level) {
        case LogLevel.Debug:
            return "debug";
        case LogLevel.Info:
            return "information";
        case LogLevel.Warning:
            return "warning";
        case LogLevel.Error:
            return "error";
        default:
            return `${level}`;
    }
}

;// ../../libs/common/src/tools/log/disabled-logger.ts

/** All disabled loggers emitted by this module are `===` to this logger. */
const disabled_logger_DISABLED_LOGGER = deepFreeze({
    debug(_content, _message) { },
    info(_content, _message) { },
    warn(_content, _message) { },
    error(_content, _message) { },
    panic(content, message) {
        if (typeof content === "string" && !message) {
            throw new Error(content);
        }
        else {
            throw new Error(message);
        }
    },
});

;// ../../libs/common/src/tools/log/util.ts
// show our GRIT - these functions implement generalized logging
//   controls and should return DISABLED_LOGGER in production.
function util_warnLoggingEnabled(logService, method, context) {
    logService.warning({
        method,
        context,
        provider: "tools/log",
        message: "Semantic logging enabled. 🦟 Please report this bug if you see it 🦟",
    });
}

;// ../../libs/common/src/tools/log/factory.ts



/** Instantiates a semantic logger that emits nothing when a message
 *  is logged.
 *  @param _context a static payload that is cloned when the logger
 *   logs a message. The `messages`, `level`, and `content` fields
 *   are reserved for use by loggers.
 */
function disabledSemanticLoggerProvider(_context) {
    return disabled_logger_DISABLED_LOGGER;
}
/** Instantiates a semantic logger that emits logs to the console.
 *  @param logService writes semantic logs to the console
 */
function consoleSemanticLoggerProvider(logService) {
    function provider(context) {
        const logger = new DefaultSemanticLogger(logService, context);
        warnLoggingEnabled(logService, "consoleSemanticLoggerProvider", context);
        return logger;
    }
    return provider;
}
/** Instantiates a semantic logger that emits logs to the console when the
 *  context's `type` matches its values.
 *  @param logService writes semantic logs to the console
 *  @param types the values to match against
 */
function enableLogForTypes(logService, types) {
    if (types.length) {
        util_warnLoggingEnabled(logService, "enableLogForTypes", { types });
    }
    function provider(context) {
        const { type } = context;
        if (typeof type === "string" && types.includes(type)) {
            const logger = new default_semantic_logger_DefaultSemanticLogger(logService, context);
            util_warnLoggingEnabled(logService, "enableLogForTypes", {
                targetType: type,
                available: types,
                loggerContext: context,
            });
            return logger;
        }
        else {
            return disabled_logger_DISABLED_LOGGER;
        }
    }
    return provider;
}
/** Instantiates a semantic logger that emits logs to the console when its enabled.
 *  @param enable logs are emitted when this is true
 *  @param logService writes semantic logs to the console
 *  @param context a static payload that is cloned when the logger
 *   logs a message.
 *
 *  @remarks The `message`, `level`, `provider`, and `content` fields
 *   are reserved for use by the semantic logging system.
 */
function ifEnabledSemanticLoggerProvider(enable, logService, context) {
    if (enable) {
        const logger = new DefaultSemanticLogger(logService, context);
        warnLoggingEnabled(logService, "ifEnabledSemanticLoggerProvider", context);
        return logger;
    }
    else {
        return DISABLED_LOGGER;
    }
}

;// ../../libs/common/src/tools/log/index.ts



;// ../../libs/common/src/tools/providers.ts


/** Constructs a system service provider. */
function createSystemServiceProvider(encryptor, state, policy, registry, logger, environment, configService) {
    let log;
    if (environment.isDev()) {
        log = enableLogForTypes(logger, []);
    }
    else {
        log = disabledSemanticLoggerProvider;
    }
    const extension = new ExtensionService(registry, {
        encryptor,
        state,
        log,
        now: Date.now,
    });
    return {
        policy,
        extension,
        log,
        configService,
        environment,
    };
}

;// ../../libs/common/src/tools/send/models/domain/send.ts
var send_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore








class Send extends Domain {
    constructor(obj) {
        super();
        if (obj == null) {
            return;
        }
        this.buildDomainModel(this, obj, {
            id: null,
            accessId: null,
            name: null,
            notes: null,
            key: null,
        }, ["id", "accessId"]);
        this.type = obj.type;
        this.authType = obj.authType;
        this.maxAccessCount = obj.maxAccessCount;
        this.accessCount = obj.accessCount;
        this.password = obj.password;
        this.disabled = obj.disabled;
        this.revisionDate = obj.revisionDate != null ? new Date(obj.revisionDate) : null;
        this.deletionDate = obj.deletionDate != null ? new Date(obj.deletionDate) : null;
        this.expirationDate = obj.expirationDate != null ? new Date(obj.expirationDate) : null;
        this.hideEmail = obj.hideEmail;
        this.authType = obj.authType;
        this.emails = obj.emails;
        switch (this.type) {
            case send_type_SendType.Text:
                this.text = new SendText(obj.text);
                break;
            case send_type_SendType.File:
                this.file = new SendFile(obj.file);
                break;
            default:
                break;
        }
    }
    decrypt(userId) {
        return send_awaiter(this, void 0, void 0, function* () {
            if (!userId) {
                throw new Error("User ID must not be null or undefined");
            }
            const model = new SendView(this);
            const keyService = utils_Utils.getContainerService().getKeyService();
            const encryptService = utils_Utils.getContainerService().getEncryptService();
            const sendKeyEncryptionKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(keyService.userKey$(userId));
            // model.key is a seed used to derive a key, not a SymmetricCryptoKey
            model.key = yield encryptService.decryptBytes(this.key, sendKeyEncryptionKey);
            model.cryptoKey = yield keyService.makeSendKey(model.key);
            model.name =
                this.name != null ? yield encryptService.decryptString(this.name, model.cryptoKey) : null;
            model.notes =
                this.notes != null ? yield encryptService.decryptString(this.notes, model.cryptoKey) : null;
            if (this.emails != null) {
                model.emails = this.emails ? this.emails.split(",").map((e) => e.trim()) : [];
            }
            else {
                model.emails = [];
            }
            switch (this.type) {
                case send_type_SendType.File:
                    model.file = yield this.file.decrypt(model.cryptoKey);
                    break;
                case send_type_SendType.Text:
                    model.text = yield this.text.decrypt(model.cryptoKey);
                    break;
                default:
                    break;
            }
            return model;
        });
    }
    static fromJSON(obj) {
        if (obj == null) {
            return null;
        }
        const revisionDate = obj.revisionDate == null ? null : new Date(obj.revisionDate);
        const expirationDate = obj.expirationDate == null ? null : new Date(obj.expirationDate);
        const deletionDate = obj.deletionDate == null ? null : new Date(obj.deletionDate);
        return Object.assign(new Send(), obj, {
            key: enc_string_EncString.fromJSON(obj.key),
            name: enc_string_EncString.fromJSON(obj.name),
            notes: enc_string_EncString.fromJSON(obj.notes),
            emails: obj.emails,
            text: SendText.fromJSON(obj.text),
            file: SendFile.fromJSON(obj.file),
            revisionDate,
            expirationDate,
            deletionDate,
        });
    }
}

;// ../../libs/common/src/tools/send/models/api/send-file.api.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

class SendFileApi extends BaseResponse {
    constructor(data = null) {
        super(data);
        if (data == null) {
            return;
        }
        this.id = this.getResponseProperty("Id");
        this.fileName = this.getResponseProperty("FileName");
        this.size = this.getResponseProperty("Size");
        this.sizeName = this.getResponseProperty("SizeName");
    }
}

;// ../../libs/common/src/tools/send/models/api/send-text.api.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

class SendTextApi extends BaseResponse {
    constructor(data = null) {
        super(data);
        if (data == null) {
            return;
        }
        this.text = this.getResponseProperty("Text");
        this.hidden = this.getResponseProperty("Hidden") || false;
    }
}

;// ../../libs/common/src/tools/send/models/request/send.request.ts



class SendRequest {
    constructor(send, fileLength) {
        this.type = send.type;
        this.fileLength = fileLength;
        this.name = send.name ? send.name.encryptedString : null;
        this.notes = send.notes ? send.notes.encryptedString : null;
        this.maxAccessCount = send.maxAccessCount;
        this.expirationDate = send.expirationDate != null ? send.expirationDate.toISOString() : null;
        this.deletionDate = send.deletionDate != null ? send.deletionDate.toISOString() : null;
        this.key = send.key != null ? send.key.encryptedString : null;
        this.password = send.password;
        this.emails = send.emails;
        this.disabled = send.disabled;
        this.hideEmail = send.hideEmail;
        this.authTYpe = send.authType;
        switch (this.type) {
            case send_type_SendType.Text:
                this.text = new SendTextApi();
                this.text.text = send.text.text != null ? send.text.text.encryptedString : null;
                this.text.hidden = send.text.hidden;
                break;
            case send_type_SendType.File:
                this.file = new SendFileApi();
                this.file.fileName = send.file.fileName != null ? send.file.fileName.encryptedString : null;
                break;
            default:
                break;
        }
    }
}

;// ../../libs/common/src/tools/send/models/response/send-access.response.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore



class send_access_response_SendAccessResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.id = this.getResponseProperty("Id");
        this.type = this.getResponseProperty("Type");
        this.name = this.getResponseProperty("Name");
        const text = this.getResponseProperty("Text");
        if (text != null) {
            this.text = new SendTextApi(text);
        }
        const file = this.getResponseProperty("File");
        if (file != null) {
            this.file = new SendFileApi(file);
        }
        this.expirationDate = this.getResponseProperty("ExpirationDate");
        this.creatorIdentifier = this.getResponseProperty("CreatorIdentifier");
    }
}

;// ../../libs/common/src/tools/send/models/response/send-file-download-data.response.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

class SendFileDownloadDataResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.id = null;
        this.url = null;
        this.id = this.getResponseProperty("Id");
        this.url = this.getResponseProperty("Url");
    }
}

;// ../../libs/common/src/tools/send/models/response/send.response.ts



class send_response_SendResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.id = this.getResponseProperty("Id");
        this.accessId = this.getResponseProperty("AccessId");
        this.type = this.getResponseProperty("Type");
        this.authType = this.getResponseProperty("AuthType");
        this.name = this.getResponseProperty("Name");
        this.notes = this.getResponseProperty("Notes");
        this.key = this.getResponseProperty("Key");
        this.maxAccessCount = this.getResponseProperty("MaxAccessCount");
        this.accessCount = this.getResponseProperty("AccessCount");
        this.revisionDate = this.getResponseProperty("RevisionDate");
        this.expirationDate = this.getResponseProperty("ExpirationDate");
        this.deletionDate = this.getResponseProperty("DeletionDate");
        this.password = this.getResponseProperty("Password");
        this.emails = this.getResponseProperty("Emails");
        this.disable = this.getResponseProperty("Disabled") || false;
        this.hideEmail = this.getResponseProperty("HideEmail") || false;
        this.authType = this.getResponseProperty("AuthType");
        const text = this.getResponseProperty("Text");
        if (text != null) {
            this.text = new SendTextApi(text);
        }
        const file = this.getResponseProperty("File");
        if (file != null) {
            this.file = new SendFileApi(file);
        }
    }
}

;// ../../libs/common/src/tools/send/models/response/send-file-upload-data.response.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


class SendFileUploadDataResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.url = null;
        this.fileUploadType = this.getResponseProperty("FileUploadType");
        const sendResponse = this.getResponseProperty("SendResponse");
        this.sendResponse = sendResponse == null ? null : new send_response_SendResponse(sendResponse);
        this.url = this.getResponseProperty("Url");
    }
}

;// ../../libs/common/src/tools/send/services/send-api.service.ts
var send_api_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};










class SendApiService {
    constructor(apiService, fileUploadService, sendService) {
        this.apiService = apiService;
        this.fileUploadService = fileUploadService;
        this.sendService = sendService;
    }
    getSend(id) {
        return send_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("GET", "/sends/" + id, null, true, true);
            return new send_response_SendResponse(r);
        });
    }
    postSendAccess(id, request, apiUrl) {
        return send_api_service_awaiter(this, void 0, void 0, function* () {
            const addSendIdHeader = (headers) => {
                headers.set("Send-Id", id);
            };
            const r = yield this.apiService.send("POST", "/sends/access/" + id, request, false, true, apiUrl, addSendIdHeader);
            return new send_access_response_SendAccessResponse(r);
        });
    }
    postSendAccessV2(accessToken, apiUrl) {
        return send_api_service_awaiter(this, void 0, void 0, function* () {
            const setAuthTokenHeader = (headers) => {
                headers.set("Authorization", "Bearer " + accessToken.token);
            };
            const r = yield this.apiService.send("POST", "/sends/access", null, false, true, apiUrl, setAuthTokenHeader);
            return new send_access_response_SendAccessResponse(r);
        });
    }
    getSendFileDownloadData(send, request, apiUrl) {
        return send_api_service_awaiter(this, void 0, void 0, function* () {
            const addSendIdHeader = (headers) => {
                headers.set("Send-Id", send.id);
            };
            const r = yield this.apiService.send("POST", "/sends/" + send.id + "/access/file/" + send.file.id, request, false, true, apiUrl, addSendIdHeader);
            return new SendFileDownloadDataResponse(r);
        });
    }
    getSendFileDownloadDataV2(send, accessToken, apiUrl) {
        return send_api_service_awaiter(this, void 0, void 0, function* () {
            const setAuthTokenHeader = (headers) => {
                headers.set("Authorization", "Bearer " + accessToken.token);
            };
            const r = yield this.apiService.send("POST", "/sends/access/file/" + send.file.id, null, false, true, apiUrl, setAuthTokenHeader);
            return new SendFileDownloadDataResponse(r);
        });
    }
    getSends() {
        return send_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("GET", "/sends", null, true, true);
            return new ListResponse(r, send_response_SendResponse);
        });
    }
    postSend(request) {
        return send_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("POST", "/sends", request, true, true);
            return new send_response_SendResponse(r);
        });
    }
    postFileTypeSend(request) {
        return send_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("POST", "/sends/file/v2", request, true, true);
            return new SendFileUploadDataResponse(r);
        });
    }
    renewSendFileUploadUrl(sendId, fileId) {
        return send_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("GET", "/sends/" + sendId + "/file/" + fileId, null, true, true);
            return new SendFileUploadDataResponse(r);
        });
    }
    postSendFile(sendId, fileId, data) {
        return this.apiService.send("POST", "/sends/" + sendId + "/file/" + fileId, data, true, false);
    }
    putSend(id, request) {
        return send_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("PUT", "/sends/" + id, request, true, true);
            return new send_response_SendResponse(r);
        });
    }
    putSendRemovePassword(id) {
        return send_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("PUT", "/sends/" + id + "/remove-password", null, true, true);
            return new send_response_SendResponse(r);
        });
    }
    deleteSend(id) {
        return this.apiService.send("DELETE", "/sends/" + id, null, true, false);
    }
    save(sendData) {
        return send_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.upload(sendData);
            const data = new SendData(response);
            yield this.sendService.upsert(data);
            return new Send(data);
        });
    }
    delete(id) {
        return send_api_service_awaiter(this, void 0, void 0, function* () {
            yield this.deleteSend(id);
            yield this.sendService.delete(id);
        });
    }
    removePassword(id) {
        return send_api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.putSendRemovePassword(id);
            const data = new SendData(response);
            yield this.sendService.upsert(data);
        });
    }
    // Send File Upload methods
    upload(sendData) {
        return send_api_service_awaiter(this, void 0, void 0, function* () {
            var _a;
            const request = new SendRequest(sendData[0], (_a = sendData[1]) === null || _a === void 0 ? void 0 : _a.buffer.byteLength);
            let response;
            if (sendData[0].id == null) {
                if (sendData[0].type === send_type_SendType.Text) {
                    response = yield this.postSend(request);
                }
                else {
                    try {
                        const uploadDataResponse = yield this.postFileTypeSend(request);
                        response = uploadDataResponse.sendResponse;
                        yield this.fileUploadService.upload(uploadDataResponse, sendData[0].file.fileName, sendData[1], this.generateMethods(uploadDataResponse, response));
                    }
                    catch (e) {
                        if (e instanceof ErrorResponse) {
                            throw new Error(e.getSingleMessage());
                        }
                        else {
                            throw e;
                        }
                    }
                }
                sendData[0].id = response.id;
                sendData[0].accessId = response.accessId;
            }
            else {
                response = yield this.putSend(sendData[0].id, request);
            }
            return response;
        });
    }
    generateMethods(uploadData, response) {
        return {
            postDirect: this.generatePostDirectCallback(response),
            renewFileUploadUrl: this.generateRenewFileUploadUrlCallback(response.id, response.file.id),
            rollback: this.generateRollbackCallback(response.id),
        };
    }
    generatePostDirectCallback(sendResponse) {
        return (data) => {
            return this.postSendFile(sendResponse.id, sendResponse.file.id, data);
        };
    }
    generateRenewFileUploadUrlCallback(sendId, fileId) {
        return () => send_api_service_awaiter(this, void 0, void 0, function* () {
            const renewResponse = yield this.renewSendFileUploadUrl(sendId, fileId);
            return renewResponse === null || renewResponse === void 0 ? void 0 : renewResponse.url;
        });
    }
    generateRollbackCallback(sendId) {
        return () => {
            return this.deleteSend(sendId);
        };
    }
}

;// ../../libs/common/src/tools/send/services/key-definitions.ts

/** Encrypted send state stored on disk */
const SEND_USER_ENCRYPTED = UserKeyDefinition.record(SEND_DISK, "sendUserEncrypted", {
    deserializer: (obj) => obj,
    clearOn: ["logout"],
});
/** Decrypted send state stored in memory */
const SEND_USER_DECRYPTED = new UserKeyDefinition(SEND_MEMORY, "sendUserDecrypted", {
    deserializer: (obj) => obj,
    clearOn: ["lock"],
});

;// ../../libs/common/src/tools/send/services/send-state.provider.ts
var send_state_provider_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


/** State provider for sends */
class SendStateProvider {
    constructor(stateProvider) {
        this.stateProvider = stateProvider;
        this.activeUserEncryptedState = this.stateProvider.getActive(SEND_USER_ENCRYPTED);
        this.encryptedState$ = this.activeUserEncryptedState.combinedState$;
        this.activeUserDecryptedState = this.stateProvider.getActive(SEND_USER_DECRYPTED);
        this.decryptedState$ = this.activeUserDecryptedState.state$;
    }
    /** Gets the encrypted sends from state for an active user */
    getEncryptedSends() {
        return send_state_provider_awaiter(this, void 0, void 0, function* () {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.encryptedState$);
        });
    }
    /** Sets the encrypted send state for an active user */
    setEncryptedSends(value, userId) {
        return send_state_provider_awaiter(this, void 0, void 0, function* () {
            yield this.stateProvider.getUser(userId, SEND_USER_ENCRYPTED).update(() => value);
        });
    }
    /** Gets the decrypted sends from state for the active user */
    getDecryptedSends() {
        return send_state_provider_awaiter(this, void 0, void 0, function* () {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.decryptedState$);
        });
    }
    /** Sets the decrypted send state for an active user */
    setDecryptedSends(value) {
        return send_state_provider_awaiter(this, void 0, void 0, function* () {
            yield this.activeUserDecryptedState.update(() => value);
        });
    }
}

;// ../../libs/common/src/tools/send/models/request/send-with-id.request.ts

class SendWithIdRequest extends SendRequest {
    constructor(send) {
        super(send);
        this.id = send.id;
    }
}

;// ../../libs/common/src/tools/send/services/send.service.ts
var send_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop.
// eslint-disable-next-line no-restricted-imports










class SendService {
    constructor(accountService, keyService, i18nService, keyGenerationService, stateProvider, encryptService, configService) {
        this.accountService = accountService;
        this.keyService = keyService;
        this.i18nService = i18nService;
        this.keyGenerationService = keyGenerationService;
        this.stateProvider = stateProvider;
        this.encryptService = encryptService;
        this.configService = configService;
        this.sendKeySalt = "bitwarden-send";
        this.sendKeyPurpose = "send";
        this.sends$ = this.stateProvider.encryptedState$.pipe((0,external_rxjs_namespaceObject.map)(([, record]) => Object.values(record || {}).map((data) => new Send(data))));
        this.sendViews$ = this.stateProvider.encryptedState$.pipe((0,external_rxjs_namespaceObject.concatMap)(([userId, record]) => this.decryptSends(Object.values(record || {}).map((data) => new Send(data)), userId)));
    }
    encrypt(model, file, password, userKey) {
        return send_service_awaiter(this, void 0, void 0, function* () {
            var _a, _b;
            let fileData = null;
            const send = new Send();
            send.id = model.id;
            send.type = model.type;
            send.disabled = model.disabled;
            send.hideEmail = model.hideEmail;
            send.maxAccessCount = model.maxAccessCount;
            send.deletionDate = model.deletionDate;
            send.expirationDate = model.expirationDate;
            if (model.key == null) {
                // Sends use a seed, stored in the URL fragment. This seed is used to derive the key that is used for encryption.
                const key = yield this.keyGenerationService.createKeyWithPurpose(128, this.sendKeyPurpose, this.sendKeySalt);
                // key.material is the seed that can be used to re-derive the key
                model.key = key.material;
                model.cryptoKey = key.derivedKey;
            }
            // Check feature flag for email OTP authentication
            const sendEmailOTPEnabled = yield this.configService.getFeatureFlag(feature_flag_enum_FeatureFlag.SendEmailOTP);
            const hasEmails = ((_b = (_a = model.emails) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0;
            if (sendEmailOTPEnabled && hasEmails) {
                send.emails = model.emails
                    .map((e) => e.trim())
                    .join(",")
                    .toLocaleLowerCase();
                send.password = null;
            }
            else {
                send.emails = null;
                if (password != null) {
                    // Note: Despite being called key, the passwordKey is not used for encryption.
                    // It is used as a static proof that the client knows the password, and has the encryption key.
                    const passwordKey = yield this.keyGenerationService.deriveKeyFromPassword(password, model.key, new PBKDF2KdfConfig(SEND_KDF_ITERATIONS));
                    send.password = passwordKey.keyB64;
                }
            }
            const userId = (yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$)).id;
            if (userKey == null) {
                userKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.userKey$(userId));
            }
            // Key is not a SymmetricCryptoKey, but key material used to derive the cryptoKey
            send.key = yield this.encryptService.encryptBytes(model.key, userKey);
            send.name =
                model.name != null
                    ? yield this.encryptService.encryptString(model.name, model.cryptoKey)
                    : null;
            send.notes =
                model.notes != null
                    ? yield this.encryptService.encryptString(model.notes, model.cryptoKey)
                    : null;
            if (send.type === send_type_SendType.Text) {
                send.text = new SendText();
                // FIXME: model.text.text can be null. encryptString should not be called with null values.
                send.text.text = yield this.encryptService.encryptString(model.text.text, model.cryptoKey);
                send.text.hidden = model.text.hidden;
            }
            else if (send.type === send_type_SendType.File) {
                send.file = new SendFile();
                if (file != null) {
                    if (file instanceof ArrayBuffer) {
                        const [name, data] = yield this.encryptFileData(model.file.fileName, file, model.cryptoKey, userId);
                        send.file.fileName = name;
                        fileData = data;
                    }
                    else {
                        fileData = yield this.parseFile(send, file, model.cryptoKey, userId);
                    }
                }
            }
            send.authType = model.authType;
            return [send, fileData];
        });
    }
    get$(id) {
        return this.sends$.pipe((0,external_rxjs_namespaceObject.distinctUntilChanged)((oldSends, newSends) => {
            const oldSend = oldSends.find((oldSend) => oldSend.id === id);
            const newSend = newSends.find((newSend) => newSend.id === id);
            if (!oldSend || !newSend) {
                // If either oldSend or newSend is not found, consider them different
                return false;
            }
            // Compare each property of the old and new Send objects
            const allPropertiesSame = Object.keys(newSend).every((key) => {
                if ((oldSend[key] != null && newSend[key] === null) ||
                    (oldSend[key] === null && newSend[key] != null)) {
                    // If a key from either old or new send is not found, and the key from the other send has a value, consider them different
                    return false;
                }
                switch (key) {
                    case "name":
                    case "notes":
                    case "key":
                        if (oldSend[key] === null && newSend[key] === null) {
                            return true;
                        }
                        return oldSend[key].encryptedString === newSend[key].encryptedString;
                    case "text":
                        if (oldSend[key].text == null && newSend[key].text == null) {
                            return true;
                        }
                        if ((oldSend[key].text != null && newSend[key].text == null) ||
                            (oldSend[key].text == null && newSend[key].text != null)) {
                            return false;
                        }
                        return oldSend[key].text.encryptedString === newSend[key].text.encryptedString;
                    case "file":
                        //Files are never updated so never will be changed.
                        return true;
                    case "revisionDate":
                    case "expirationDate":
                    case "deletionDate":
                        if (oldSend[key] === null && newSend[key] === null) {
                            return true;
                        }
                        return oldSend[key].getTime() === newSend[key].getTime();
                    default:
                        // For other properties, compare directly
                        return oldSend[key] === newSend[key];
                }
            });
            return allPropertiesSame;
        }), (0,external_rxjs_namespaceObject.map)((sends) => sends.find((o) => o.id === id)));
    }
    getFromState(id) {
        return send_service_awaiter(this, void 0, void 0, function* () {
            const [, sends] = yield this.stateProvider.getEncryptedSends();
            // eslint-disable-next-line
            if (sends == null || !sends.hasOwnProperty(id)) {
                return null;
            }
            return new Send(sends[id]);
        });
    }
    getAll() {
        return send_service_awaiter(this, void 0, void 0, function* () {
            const [, sends] = yield this.stateProvider.getEncryptedSends();
            const response = [];
            for (const id in sends) {
                // eslint-disable-next-line
                if (sends.hasOwnProperty(id)) {
                    response.push(new Send(sends[id]));
                }
            }
            return response;
        });
    }
    getAllDecryptedFromState(userId) {
        return send_service_awaiter(this, void 0, void 0, function* () {
            if (!userId) {
                throw new Error("User ID must not be null or undefined");
            }
            let decSends = yield this.stateProvider.getDecryptedSends();
            if (decSends != null) {
                return decSends;
            }
            decSends = [];
            const hasKey = yield this.keyService.hasUserKey(userId);
            if (!hasKey) {
                throw new Error("No user key found.");
            }
            const promises = [];
            const sends = yield this.getAll();
            sends.forEach((send) => {
                promises.push(send.decrypt(userId).then((f) => decSends.push(f)));
            });
            yield Promise.all(promises);
            decSends.sort(utils_Utils.getSortFunction(this.i18nService, "name"));
            yield this.stateProvider.setDecryptedSends(decSends);
            return decSends;
        });
    }
    upsert(send) {
        return send_service_awaiter(this, void 0, void 0, function* () {
            const [userId, currentSends] = yield this.stateProvider.getEncryptedSends();
            let sends = currentSends;
            if (sends == null) {
                sends = {};
            }
            if (send instanceof SendData) {
                const s = send;
                sends[s.id] = s;
            }
            else {
                send.forEach((s) => {
                    sends[s.id] = s;
                });
            }
            yield this.replace(sends, userId);
        });
    }
    delete(id) {
        return send_service_awaiter(this, void 0, void 0, function* () {
            const [userId, sends] = yield this.stateProvider.getEncryptedSends();
            if (sends == null) {
                return;
            }
            if (typeof id === "string") {
                if (sends[id] == null) {
                    return;
                }
                delete sends[id];
            }
            else {
                id.forEach((i) => {
                    delete sends[i];
                });
            }
            yield this.replace(sends, userId);
        });
    }
    replace(sends, userId) {
        return send_service_awaiter(this, void 0, void 0, function* () {
            yield this.stateProvider.setEncryptedSends(sends, userId);
        });
    }
    getRotatedData(originalUserKey, newUserKey, userId) {
        return send_service_awaiter(this, void 0, void 0, function* () {
            if (newUserKey == null) {
                throw new Error("New user key is required for rotation.");
            }
            if (originalUserKey == null) {
                throw new Error("Original user key is required for rotation.");
            }
            const req = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sends$.pipe((0,external_rxjs_namespaceObject.concatMap)((sends) => send_service_awaiter(this, void 0, void 0, function* () { return this.toRotatedKeyRequestMap(sends, originalUserKey, newUserKey); }))));
            // separate return for easier debugging
            return req;
        });
    }
    toRotatedKeyRequestMap(sends, originalUserKey, rotateUserKey) {
        return send_service_awaiter(this, void 0, void 0, function* () {
            const requests = yield Promise.all(sends.map((send) => send_service_awaiter(this, void 0, void 0, function* () {
                // Send key is not a key but a 16 byte seed used to derive the key
                const sendKey = yield this.encryptService.decryptBytes(send.key, originalUserKey);
                send.key = yield this.encryptService.encryptBytes(sendKey, rotateUserKey);
                return new SendWithIdRequest(send);
            })));
            return requests;
        });
    }
    parseFile(send, file, key, userId) {
        return new Promise((resolve, reject) => {
            const reader = new FileReader();
            reader.readAsArrayBuffer(file);
            reader.onload = (evt) => send_service_awaiter(this, void 0, void 0, function* () {
                try {
                    const [name, data] = yield this.encryptFileData(file.name, evt.target.result, key, userId);
                    send.file.fileName = name;
                    resolve(data);
                }
                catch (e) {
                    reject(e);
                }
            });
            reader.onerror = () => {
                reject("Error reading file.");
            };
        });
    }
    encryptFileData(fileName, data, key, userId) {
        return send_service_awaiter(this, void 0, void 0, function* () {
            if (key == null) {
                key = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.userKey$(userId));
            }
            const encFileName = yield this.encryptService.encryptString(fileName, key);
            const encFileData = yield this.encryptService.encryptFileData(new Uint8Array(data), key);
            return [encFileName, encFileData];
        });
    }
    decryptSends(sends, userId) {
        return send_service_awaiter(this, void 0, void 0, function* () {
            const decryptSendPromises = sends.map((s) => s.decrypt(userId));
            const decryptedSends = yield Promise.all(decryptSendPromises);
            decryptedSends.sort(utils_Utils.getSortFunction(this.i18nService, "name"));
            return decryptedSends;
        });
    }
}

;// ../../libs/common/src/vault/services/cipher-authorization.service.ts




/**
 * Service for managing user cipher authorization.
 */
class CipherAuthorizationService {
}
/**
 * {@link CipherAuthorizationService}
 */
class DefaultCipherAuthorizationService {
    constructor(collectionService, organizationService, accountService) {
        this.collectionService = collectionService;
        this.organizationService = organizationService;
        this.accountService = accountService;
        this.organization$ = (cipher) => this.accountService.activeAccount$.pipe(account_service_getUserId, (0,external_rxjs_namespaceObject.switchMap)((userId) => this.organizationService.organizations$(userId)), (0,external_rxjs_namespaceObject.map)((orgs) => orgs.find((org) => org.id === cipher.organizationId)));
    }
    /**
     *
     * {@link CipherAuthorizationService.canDeleteCipher$}
     */
    canDeleteCipher$(cipher, isAdminConsoleAction) {
        return this.organization$(cipher).pipe((0,external_rxjs_namespaceObject.map)((organization) => {
            var _a;
            if (isAdminConsoleAction) {
                // If the user is an admin, they can delete an unassigned cipher
                if (!cipher.collectionIds || cipher.collectionIds.length === 0) {
                    return (organization === null || organization === void 0 ? void 0 : organization.canEditUnassignedCiphers) === true;
                }
                if (organization === null || organization === void 0 ? void 0 : organization.canEditAllCiphers) {
                    return true;
                }
            }
            return !!((_a = cipher.permissions) === null || _a === void 0 ? void 0 : _a.delete);
        }));
    }
    /**
     *
     * {@link CipherAuthorizationService.canRestoreCipher$}
     */
    canRestoreCipher$(cipher, isAdminConsoleAction) {
        return this.organization$(cipher).pipe((0,external_rxjs_namespaceObject.map)((organization) => {
            var _a;
            if (isAdminConsoleAction) {
                // If the user is an admin, they can restore an unassigned cipher
                if (!cipher.collectionIds || cipher.collectionIds.length === 0) {
                    return (organization === null || organization === void 0 ? void 0 : organization.canEditUnassignedCiphers) === true;
                }
                if (organization === null || organization === void 0 ? void 0 : organization.canEditAllCiphers) {
                    return true;
                }
            }
            return !!((_a = cipher.permissions) === null || _a === void 0 ? void 0 : _a.restore);
        }));
    }
    /**
     *
     * {@link CipherAuthorizationService.canEditCipher$}
     */
    canEditCipher$(cipher, isAdminConsoleAction = false) {
        return this.organization$(cipher).pipe((0,external_rxjs_namespaceObject.map)((organization) => {
            if (isAdminConsoleAction) {
                // If the user is an admin, they can edit an unassigned cipher
                if (!cipher.collectionIds || cipher.collectionIds.length === 0) {
                    return (organization === null || organization === void 0 ? void 0 : organization.canEditUnassignedCiphers) === true;
                }
                if (organization === null || organization === void 0 ? void 0 : organization.canEditAllCiphers) {
                    return true;
                }
            }
            return !!cipher.edit;
        }));
    }
    /**
     * {@link CipherAuthorizationService.canCloneCipher$}
     */
    canCloneCipher$(cipher, isAdminConsoleAction) {
        if (cipher.organizationId == null) {
            return (0,external_rxjs_namespaceObject.of)(true);
        }
        return (0,external_rxjs_namespaceObject.combineLatest)([
            this.organization$(cipher),
            this.accountService.activeAccount$.pipe(account_service_getUserId),
        ]).pipe((0,external_rxjs_namespaceObject.switchMap)(([organization, userId]) => {
            var _a;
            // Admins and custom users can always clone when in the Admin Console
            if (isAdminConsoleAction &&
                organization &&
                (organization.isAdmin || ((_a = organization.permissions) === null || _a === void 0 ? void 0 : _a.editAnyCollection))) {
                return (0,external_rxjs_namespaceObject.of)(true);
            }
            return this.collectionService.decryptedCollections$(userId).pipe(getByIds(cipher.collectionIds.map(uuidAsString)), (0,external_rxjs_namespaceObject.map)((allCollections) => allCollections.some((collection) => collection.manage)));
        }), (0,external_rxjs_namespaceObject.shareReplay)({ bufferSize: 1, refCount: false }));
    }
}

;// ../../libs/common/src/vault/services/cipher-sdk.service.ts
var cipher_sdk_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var cipher_sdk_service_addDisposableResource = (undefined && undefined.__addDisposableResource) || function (env, value, async) {
    if (value !== null && value !== void 0) {
        if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
        var dispose, inner;
        if (async) {
            if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
            dispose = value[Symbol.asyncDispose];
        }
        if (dispose === void 0) {
            if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
            dispose = value[Symbol.dispose];
            if (async) inner = dispose;
        }
        if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
        if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
        env.stack.push({ value: value, dispose: dispose, async: async });
    }
    else if (async) {
        env.stack.push({ async: true });
    }
    return value;
};
var cipher_sdk_service_disposeResources = (undefined && undefined.__disposeResources) || (function (SuppressedError) {
    return function (env) {
        function fail(e) {
            env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
            env.hasError = true;
        }
        var r, s = 0;
        function next() {
            while (r = env.stack.pop()) {
                try {
                    if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
                    if (r.dispose) {
                        var result = r.dispose.call(r.value);
                        if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
                    }
                    else s |= 1;
                }
                catch (e) {
                    fail(e);
                }
            }
            if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
            if (env.hasError) throw env.error;
        }
        return next();
    };
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
    var e = new Error(message);
    return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
});





class DefaultCipherSdkService {
    constructor(sdkService, logService) {
        this.sdkService = sdkService;
        this.logService = logService;
    }
    createWithServer(cipherView, userId, orgAdmin) {
        return cipher_sdk_service_awaiter(this, void 0, void 0, function* () {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkService.userClient$(userId).pipe((0,external_rxjs_namespaceObject.switchMap)((sdk) => cipher_sdk_service_awaiter(this, void 0, void 0, function* () {
                const env_1 = { stack: [], error: void 0, hasError: false };
                try {
                    if (!sdk) {
                        throw new Error("SDK not available");
                    }
                    const ref = cipher_sdk_service_addDisposableResource(env_1, sdk.take(), false);
                    const sdkCiphersClient = ref.value.vault().ciphers();
                    const sdkCreateRequest = cipherView.toSdkCreateCipherRequest(sdkCiphersClient);
                    let result;
                    if (orgAdmin) {
                        result = yield sdkCiphersClient.admin().create(sdkCreateRequest);
                    }
                    else {
                        result = yield sdkCiphersClient.create(sdkCreateRequest);
                    }
                    return CipherView.fromSdkCipherView(result, sdkCiphersClient);
                }
                catch (e_1) {
                    env_1.error = e_1;
                    env_1.hasError = true;
                }
                finally {
                    cipher_sdk_service_disposeResources(env_1);
                }
            })), (0,external_rxjs_namespaceObject.catchError)((error) => {
                this.logService.error(`Failed to create cipher: ${error}`);
                throw error;
            })));
        });
    }
    updateWithServer(cipher, userId, originalCipherView, orgAdmin) {
        return cipher_sdk_service_awaiter(this, void 0, void 0, function* () {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkService.userClient$(userId).pipe((0,external_rxjs_namespaceObject.switchMap)((sdk) => cipher_sdk_service_awaiter(this, void 0, void 0, function* () {
                const env_2 = { stack: [], error: void 0, hasError: false };
                try {
                    if (!sdk) {
                        throw new Error("SDK not available");
                    }
                    const ref = cipher_sdk_service_addDisposableResource(env_2, sdk.take(), false);
                    const sdkCiphersClient = ref.value.vault().ciphers();
                    const sdkUpdateRequest = cipher.toSdkUpdateCipherRequest(sdkCiphersClient);
                    let result;
                    if (orgAdmin) {
                        result = yield sdkCiphersClient
                            .admin()
                            .edit(sdkUpdateRequest, (originalCipherView === null || originalCipherView === void 0 ? void 0 : originalCipherView.toSdkCipherView()) || new CipherView().toSdkCipherView());
                    }
                    else {
                        result = yield sdkCiphersClient.edit(sdkUpdateRequest);
                    }
                    return CipherView.fromSdkCipherView(result, sdkCiphersClient);
                }
                catch (e_2) {
                    env_2.error = e_2;
                    env_2.hasError = true;
                }
                finally {
                    cipher_sdk_service_disposeResources(env_2);
                }
            })), (0,external_rxjs_namespaceObject.catchError)((error) => {
                this.logService.error(`Failed to update cipher: ${error}`);
                throw error;
            })));
        });
    }
    deleteWithServer(id_1, userId_1) {
        return cipher_sdk_service_awaiter(this, arguments, void 0, function* (id, userId, asAdmin = false) {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkService.userClient$(userId).pipe((0,external_rxjs_namespaceObject.switchMap)((sdk) => cipher_sdk_service_awaiter(this, void 0, void 0, function* () {
                const env_3 = { stack: [], error: void 0, hasError: false };
                try {
                    if (!sdk) {
                        throw new Error("SDK not available");
                    }
                    const ref = cipher_sdk_service_addDisposableResource(env_3, sdk.take(), false);
                    if (asAdmin) {
                        yield ref.value.vault().ciphers().admin().delete(asUuid(id));
                    }
                    else {
                        yield ref.value.vault().ciphers().delete(asUuid(id));
                    }
                }
                catch (e_3) {
                    env_3.error = e_3;
                    env_3.hasError = true;
                }
                finally {
                    cipher_sdk_service_disposeResources(env_3);
                }
            })), (0,external_rxjs_namespaceObject.catchError)((error) => {
                this.logService.error(`Failed to delete cipher: ${error}`);
                throw error;
            })));
        });
    }
    deleteManyWithServer(ids_1, userId_1) {
        return cipher_sdk_service_awaiter(this, arguments, void 0, function* (ids, userId, asAdmin = false, orgId) {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkService.userClient$(userId).pipe((0,external_rxjs_namespaceObject.switchMap)((sdk) => cipher_sdk_service_awaiter(this, void 0, void 0, function* () {
                const env_4 = { stack: [], error: void 0, hasError: false };
                try {
                    if (!sdk) {
                        throw new Error("SDK not available");
                    }
                    const ref = cipher_sdk_service_addDisposableResource(env_4, sdk.take(), false);
                    if (asAdmin) {
                        if (orgId == null) {
                            throw new Error("Organization ID is required for admin delete.");
                        }
                        yield ref.value
                            .vault()
                            .ciphers()
                            .admin()
                            .delete_many(ids.map((id) => asUuid(id)), asUuid(orgId));
                    }
                    else {
                        yield ref.value
                            .vault()
                            .ciphers()
                            .delete_many(ids.map((id) => asUuid(id)));
                    }
                }
                catch (e_4) {
                    env_4.error = e_4;
                    env_4.hasError = true;
                }
                finally {
                    cipher_sdk_service_disposeResources(env_4);
                }
            })), (0,external_rxjs_namespaceObject.catchError)((error) => {
                this.logService.error(`Failed to delete multiple ciphers: ${error}`);
                throw error;
            })));
        });
    }
    softDeleteWithServer(id_1, userId_1) {
        return cipher_sdk_service_awaiter(this, arguments, void 0, function* (id, userId, asAdmin = false) {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkService.userClient$(userId).pipe((0,external_rxjs_namespaceObject.switchMap)((sdk) => cipher_sdk_service_awaiter(this, void 0, void 0, function* () {
                const env_5 = { stack: [], error: void 0, hasError: false };
                try {
                    if (!sdk) {
                        throw new Error("SDK not available");
                    }
                    const ref = cipher_sdk_service_addDisposableResource(env_5, sdk.take(), false);
                    if (asAdmin) {
                        yield ref.value.vault().ciphers().admin().soft_delete(asUuid(id));
                    }
                    else {
                        yield ref.value.vault().ciphers().soft_delete(asUuid(id));
                    }
                }
                catch (e_5) {
                    env_5.error = e_5;
                    env_5.hasError = true;
                }
                finally {
                    cipher_sdk_service_disposeResources(env_5);
                }
            })), (0,external_rxjs_namespaceObject.catchError)((error) => {
                this.logService.error(`Failed to soft delete cipher: ${error}`);
                throw error;
            })));
        });
    }
    softDeleteManyWithServer(ids_1, userId_1) {
        return cipher_sdk_service_awaiter(this, arguments, void 0, function* (ids, userId, asAdmin = false, orgId) {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkService.userClient$(userId).pipe((0,external_rxjs_namespaceObject.switchMap)((sdk) => cipher_sdk_service_awaiter(this, void 0, void 0, function* () {
                const env_6 = { stack: [], error: void 0, hasError: false };
                try {
                    if (!sdk) {
                        throw new Error("SDK not available");
                    }
                    const ref = cipher_sdk_service_addDisposableResource(env_6, sdk.take(), false);
                    if (asAdmin) {
                        if (orgId == null) {
                            throw new Error("Organization ID is required for admin soft delete.");
                        }
                        yield ref.value
                            .vault()
                            .ciphers()
                            .admin()
                            .soft_delete_many(ids.map((id) => asUuid(id)), asUuid(orgId));
                    }
                    else {
                        yield ref.value
                            .vault()
                            .ciphers()
                            .soft_delete_many(ids.map((id) => asUuid(id)));
                    }
                }
                catch (e_6) {
                    env_6.error = e_6;
                    env_6.hasError = true;
                }
                finally {
                    cipher_sdk_service_disposeResources(env_6);
                }
            })), (0,external_rxjs_namespaceObject.catchError)((error) => {
                this.logService.error(`Failed to soft delete multiple ciphers: ${error}`);
                throw error;
            })));
        });
    }
    restoreWithServer(id_1, userId_1) {
        return cipher_sdk_service_awaiter(this, arguments, void 0, function* (id, userId, asAdmin = false) {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkService.userClient$(userId).pipe((0,external_rxjs_namespaceObject.switchMap)((sdk) => cipher_sdk_service_awaiter(this, void 0, void 0, function* () {
                const env_7 = { stack: [], error: void 0, hasError: false };
                try {
                    if (!sdk) {
                        throw new Error("SDK not available");
                    }
                    const ref = cipher_sdk_service_addDisposableResource(env_7, sdk.take(), false);
                    if (asAdmin) {
                        yield ref.value.vault().ciphers().admin().restore(asUuid(id));
                    }
                    else {
                        yield ref.value.vault().ciphers().restore(asUuid(id));
                    }
                }
                catch (e_7) {
                    env_7.error = e_7;
                    env_7.hasError = true;
                }
                finally {
                    cipher_sdk_service_disposeResources(env_7);
                }
            })), (0,external_rxjs_namespaceObject.catchError)((error) => {
                this.logService.error(`Failed to restore cipher: ${error}`);
                throw error;
            })));
        });
    }
    restoreManyWithServer(ids, userId, orgId) {
        return cipher_sdk_service_awaiter(this, void 0, void 0, function* () {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkService.userClient$(userId).pipe((0,external_rxjs_namespaceObject.switchMap)((sdk) => cipher_sdk_service_awaiter(this, void 0, void 0, function* () {
                const env_8 = { stack: [], error: void 0, hasError: false };
                try {
                    if (!sdk) {
                        throw new Error("SDK not available");
                    }
                    const ref = cipher_sdk_service_addDisposableResource(env_8, sdk.take(), false);
                    // No longer using an asAdmin Param. Org Vault bulkRestore will assess if an item is unassigned or editable
                    // The Org Vault will pass those ids an array as well as the orgId when calling bulkRestore
                    if (orgId) {
                        yield ref.value
                            .vault()
                            .ciphers()
                            .admin()
                            .restore_many(ids.map((id) => asUuid(id)), asUuid(orgId));
                    }
                    else {
                        yield ref.value
                            .vault()
                            .ciphers()
                            .restore_many(ids.map((id) => asUuid(id)));
                    }
                }
                catch (e_8) {
                    env_8.error = e_8;
                    env_8.hasError = true;
                }
                finally {
                    cipher_sdk_service_disposeResources(env_8);
                }
            })), (0,external_rxjs_namespaceObject.catchError)((error) => {
                this.logService.error(`Failed to restore multiple ciphers: ${error}`);
                throw error;
            })));
        });
    }
    getAllDecrypted(userId) {
        return cipher_sdk_service_awaiter(this, void 0, void 0, function* () {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkService.userClient$(userId).pipe((0,external_rxjs_namespaceObject.switchMap)((sdk) => cipher_sdk_service_awaiter(this, void 0, void 0, function* () {
                var _a, _b;
                const env_9 = { stack: [], error: void 0, hasError: false };
                try {
                    if (!sdk) {
                        throw new Error("SDK not available");
                    }
                    const ref = cipher_sdk_service_addDisposableResource(env_9, sdk.take(), false);
                    const decryptResult = yield ref.value.vault().ciphers().get_all();
                    const successes = [...((_a = decryptResult.successes) !== null && _a !== void 0 ? _a : [])]
                        .map((sdkCipherView) => CipherView.fromSdkCipherView(sdkCipherView))
                        .filter((v) => v !== undefined);
                    const failures = [...((_b = decryptResult.failures) !== null && _b !== void 0 ? _b : [])].map((failure) => {
                        const cipherView = new CipherView(Cipher.fromSdkCipher(failure));
                        cipherView.name = DECRYPT_ERROR;
                        cipherView.decryptionFailure = true;
                        return cipherView;
                    });
                    return { successes, failures };
                }
                catch (e_9) {
                    env_9.error = e_9;
                    env_9.hasError = true;
                }
                finally {
                    cipher_sdk_service_disposeResources(env_9);
                }
            })), (0,external_rxjs_namespaceObject.catchError)((error) => {
                this.logService.error(`Failed to list and decrypt ciphers: ${error}`);
                throw error;
            })));
        });
    }
    getAllFromApiForOrganization(organizationId, userId, includeMemberItems) {
        return cipher_sdk_service_awaiter(this, void 0, void 0, function* () {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkService.userClient$(userId).pipe((0,external_rxjs_namespaceObject.switchMap)((sdk) => cipher_sdk_service_awaiter(this, void 0, void 0, function* () {
                const env_10 = { stack: [], error: void 0, hasError: false };
                try {
                    if (!sdk) {
                        throw new Error("SDK not available");
                    }
                    const ref = cipher_sdk_service_addDisposableResource(env_10, sdk.take(), false);
                    const result = yield ref.value
                        .vault()
                        .ciphers()
                        .admin()
                        .list_org_ciphers(asUuid(organizationId), includeMemberItems);
                    const ciphers = result.ciphers
                        .map((c) => Cipher.fromSdkCipher(c))
                        .filter((c) => c !== undefined);
                    return [ciphers, result.listViews];
                }
                catch (e_10) {
                    env_10.error = e_10;
                    env_10.hasError = true;
                }
                finally {
                    cipher_sdk_service_disposeResources(env_10);
                }
            })), (0,external_rxjs_namespaceObject.catchError)((error) => {
                this.logService.error(`Failed to list organization ciphers: ${error}`);
                throw error;
            })));
        });
    }
}

;// ../../libs/common/src/vault/utils/observable-utilities.ts

function perUserCache$(create, clearBuffer$ = undefined) {
    const cache = new Map();
    return (userId) => {
        let observable = cache.get(userId);
        if (!observable) {
            clearBuffer$ !== null && clearBuffer$ !== void 0 ? clearBuffer$ : (clearBuffer$ = external_rxjs_namespaceObject.EMPTY);
            observable = (0,external_rxjs_namespaceObject.merge)(create(userId), clearBuffer$.pipe((0,external_rxjs_namespaceObject.filter)((clearId) => clearId === userId || clearId === null), (0,external_rxjs_namespaceObject.map)(() => null))).pipe((0,external_rxjs_namespaceObject.shareReplay)({ bufferSize: 1, refCount: false }));
            cache.set(userId, observable);
        }
        return observable;
    };
}
/**
 * Strongly typed observable operator that filters out null/undefined values and adjusts the return type to
 * be non-nullable.
 *
 * @example
 * ```ts
 * const source$ = of(1, null, 2, undefined, 3);
 * source$.pipe(filterOutNullish()).subscribe(console.log);
 * // Output: 1, 2, 3
 * ```
 */
function filterOutNullish() {
    return (0,external_rxjs_namespaceObject.filter)((v) => v != null);
}

;// ../../libs/common/src/vault/models/domain/sorted-ciphers-cache.ts
const CacheTTL = 3000;
class SortedCiphersCache {
    constructor(comparator) {
        this.comparator = comparator;
        this.sortedCiphersByUrl = new Map();
        this.timeouts = new Map();
    }
    isCached(url) {
        return this.sortedCiphersByUrl.has(url);
    }
    addCiphers(url, ciphers) {
        ciphers.sort(this.comparator);
        this.sortedCiphersByUrl.set(url, new Ciphers(ciphers));
        this.resetTimer(url);
    }
    getLastUsed(url) {
        this.resetTimer(url);
        return this.isCached(url) ? this.sortedCiphersByUrl.get(url).getLastUsed() : null;
    }
    getLastLaunched(url) {
        return this.isCached(url) ? this.sortedCiphersByUrl.get(url).getLastLaunched() : null;
    }
    getNext(url) {
        this.resetTimer(url);
        return this.isCached(url) ? this.sortedCiphersByUrl.get(url).getNext() : null;
    }
    updateLastUsedIndex(url) {
        if (this.isCached(url)) {
            this.sortedCiphersByUrl.get(url).updateLastUsedIndex();
        }
    }
    clear() {
        this.sortedCiphersByUrl.clear();
        this.timeouts.clear();
    }
    resetTimer(url) {
        clearTimeout(this.timeouts.get(url));
        this.timeouts.set(url, setTimeout(() => {
            this.sortedCiphersByUrl.delete(url);
            this.timeouts.delete(url);
        }, CacheTTL));
    }
}
class Ciphers {
    constructor(ciphers) {
        this.ciphers = ciphers;
        this.lastUsedIndex = -1;
    }
    getLastUsed() {
        this.lastUsedIndex = Math.max(this.lastUsedIndex, 0);
        return this.ciphers[this.lastUsedIndex];
    }
    getLastLaunched() {
        const usedCiphers = this.ciphers.filter((cipher) => { var _a; return (_a = cipher.localData) === null || _a === void 0 ? void 0 : _a.lastLaunched; });
        const sortedCiphers = usedCiphers.sort((x, y) => y.localData.lastLaunched.valueOf() - x.localData.lastLaunched.valueOf());
        return sortedCiphers[0];
    }
    getNextIndex() {
        return (this.lastUsedIndex + 1) % this.ciphers.length;
    }
    getNext() {
        return this.ciphers[this.getNextIndex()];
    }
    updateLastUsedIndex() {
        this.lastUsedIndex = this.getNextIndex();
    }
}

;// ../../libs/common/src/vault/models/request/cipher-bulk-delete.request.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
class CipherBulkDeleteRequest {
    constructor(ids, organizationId) {
        this.ids = ids == null ? [] : ids;
        this.organizationId = organizationId;
    }
}

;// ../../libs/common/src/vault/models/request/cipher-bulk-move.request.ts
class CipherBulkMoveRequest {
    constructor(ids, folderId) {
        this.ids = ids == null ? [] : ids;
        this.folderId = folderId;
    }
}

;// ../../libs/common/src/vault/models/request/cipher-bulk-restore.request.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
class CipherBulkRestoreRequest {
    constructor(ids, organizationId) {
        this.ids = ids == null ? [] : ids;
        this.organizationId = organizationId;
    }
}

;// ../../libs/common/src/vault/models/request/attachment.request.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
class AttachmentRequest {
}

;// ../../libs/common/src/vault/models/request/cipher.request.ts










class CipherRequest {
    constructor({ cipher, encryptedFor }) {
        var _a, _b, _c;
        this.type = cipher.type;
        this.encryptedFor = encryptedFor;
        this.folderId = cipher.folderId;
        this.organizationId = cipher.organizationId;
        this.name = cipher.name ? cipher.name.encryptedString : null;
        this.notes = cipher.notes ? cipher.notes.encryptedString : null;
        this.favorite = cipher.favorite;
        this.lastKnownRevisionDate = cipher.revisionDate;
        this.archivedDate = cipher.archivedDate;
        this.reprompt = cipher.reprompt;
        this.key = (_a = cipher.key) === null || _a === void 0 ? void 0 : _a.encryptedString;
        switch (this.type) {
            case CipherType.Login:
                this.login = new LoginApi();
                this.login.uris =
                    (_c = (_b = cipher.login.uris) === null || _b === void 0 ? void 0 : _b.map((u) => {
                        const uri = new LoginUriApi();
                        uri.uri = u.uri != null ? u.uri.encryptedString : null;
                        uri.match = u.match != null ? u.match : null;
                        uri.uriChecksum = u.uriChecksum != null ? u.uriChecksum.encryptedString : null;
                        return uri;
                    })) !== null && _c !== void 0 ? _c : [];
                this.login.username = cipher.login.username ? cipher.login.username.encryptedString : null;
                this.login.password = cipher.login.password ? cipher.login.password.encryptedString : null;
                this.login.passwordRevisionDate =
                    cipher.login.passwordRevisionDate != null
                        ? cipher.login.passwordRevisionDate.toISOString()
                        : null;
                this.login.totp = cipher.login.totp ? cipher.login.totp.encryptedString : null;
                this.login.autofillOnPageLoad = cipher.login.autofillOnPageLoad;
                if (cipher.login.fido2Credentials != null) {
                    this.login.fido2Credentials = cipher.login.fido2Credentials.map((key) => {
                        const keyApi = new Fido2CredentialApi();
                        keyApi.credentialId =
                            key.credentialId != null ? key.credentialId.encryptedString : null;
                        keyApi.keyType =
                            key.keyType != null ? key.keyType.encryptedString : null;
                        keyApi.keyAlgorithm =
                            key.keyAlgorithm != null ? key.keyAlgorithm.encryptedString : null;
                        keyApi.keyCurve =
                            key.keyCurve != null ? key.keyCurve.encryptedString : null;
                        keyApi.keyValue = key.keyValue != null ? key.keyValue.encryptedString : null;
                        keyApi.rpId = key.rpId != null ? key.rpId.encryptedString : null;
                        keyApi.rpName = key.rpName != null ? key.rpName.encryptedString : null;
                        keyApi.counter = key.counter != null ? key.counter.encryptedString : null;
                        keyApi.userHandle = key.userHandle != null ? key.userHandle.encryptedString : null;
                        keyApi.userName = key.userName != null ? key.userName.encryptedString : null;
                        keyApi.userDisplayName =
                            key.userDisplayName != null ? key.userDisplayName.encryptedString : null;
                        keyApi.discoverable =
                            key.discoverable != null ? key.discoverable.encryptedString : null;
                        keyApi.creationDate = key.creationDate != null ? key.creationDate.toISOString() : null;
                        return keyApi;
                    });
                }
                break;
            case CipherType.SecureNote:
                this.secureNote = new SecureNoteApi();
                this.secureNote.type = cipher.secureNote.type;
                break;
            case CipherType.SshKey:
                this.sshKey = new SshKeyApi();
                this.sshKey.privateKey =
                    cipher.sshKey.privateKey != null ? cipher.sshKey.privateKey.encryptedString : null;
                this.sshKey.publicKey =
                    cipher.sshKey.publicKey != null ? cipher.sshKey.publicKey.encryptedString : null;
                this.sshKey.keyFingerprint =
                    cipher.sshKey.keyFingerprint != null
                        ? cipher.sshKey.keyFingerprint.encryptedString
                        : null;
                break;
            case CipherType.Card:
                this.card = new CardApi();
                this.card.cardholderName =
                    cipher.card.cardholderName != null ? cipher.card.cardholderName.encryptedString : null;
                this.card.brand = cipher.card.brand != null ? cipher.card.brand.encryptedString : null;
                this.card.number = cipher.card.number != null ? cipher.card.number.encryptedString : null;
                this.card.expMonth =
                    cipher.card.expMonth != null ? cipher.card.expMonth.encryptedString : null;
                this.card.expYear =
                    cipher.card.expYear != null ? cipher.card.expYear.encryptedString : null;
                this.card.code = cipher.card.code != null ? cipher.card.code.encryptedString : null;
                break;
            case CipherType.Identity:
                this.identity = new IdentityApi();
                this.identity.title =
                    cipher.identity.title != null ? cipher.identity.title.encryptedString : null;
                this.identity.firstName =
                    cipher.identity.firstName != null ? cipher.identity.firstName.encryptedString : null;
                this.identity.middleName =
                    cipher.identity.middleName != null ? cipher.identity.middleName.encryptedString : null;
                this.identity.lastName =
                    cipher.identity.lastName != null ? cipher.identity.lastName.encryptedString : null;
                this.identity.address1 =
                    cipher.identity.address1 != null ? cipher.identity.address1.encryptedString : null;
                this.identity.address2 =
                    cipher.identity.address2 != null ? cipher.identity.address2.encryptedString : null;
                this.identity.address3 =
                    cipher.identity.address3 != null ? cipher.identity.address3.encryptedString : null;
                this.identity.city =
                    cipher.identity.city != null ? cipher.identity.city.encryptedString : null;
                this.identity.state =
                    cipher.identity.state != null ? cipher.identity.state.encryptedString : null;
                this.identity.postalCode =
                    cipher.identity.postalCode != null ? cipher.identity.postalCode.encryptedString : null;
                this.identity.country =
                    cipher.identity.country != null ? cipher.identity.country.encryptedString : null;
                this.identity.company =
                    cipher.identity.company != null ? cipher.identity.company.encryptedString : null;
                this.identity.email =
                    cipher.identity.email != null ? cipher.identity.email.encryptedString : null;
                this.identity.phone =
                    cipher.identity.phone != null ? cipher.identity.phone.encryptedString : null;
                this.identity.ssn =
                    cipher.identity.ssn != null ? cipher.identity.ssn.encryptedString : null;
                this.identity.username =
                    cipher.identity.username != null ? cipher.identity.username.encryptedString : null;
                this.identity.passportNumber =
                    cipher.identity.passportNumber != null
                        ? cipher.identity.passportNumber.encryptedString
                        : null;
                this.identity.licenseNumber =
                    cipher.identity.licenseNumber != null
                        ? cipher.identity.licenseNumber.encryptedString
                        : null;
                break;
            default:
                break;
        }
        if (cipher.fields != null) {
            this.fields = cipher.fields.map((f) => {
                const field = new FieldApi();
                field.type = f.type;
                field.name = f.name ? f.name.encryptedString : null;
                field.value = f.value ? f.value.encryptedString : null;
                field.linkedId = f.linkedId;
                return field;
            });
        }
        if (cipher.passwordHistory != null) {
            this.passwordHistory = [];
            cipher.passwordHistory.forEach((ph) => {
                this.passwordHistory.push({
                    lastUsedDate: ph.lastUsedDate,
                    password: ph.password ? ph.password.encryptedString : null,
                });
            });
        }
        if (cipher.attachments != null) {
            this.attachments = {};
            this.attachments2 = {};
            cipher.attachments.forEach((attachment) => {
                const fileName = attachment.fileName ? attachment.fileName.encryptedString : null;
                this.attachments[attachment.id] = fileName;
                const attachmentRequest = new AttachmentRequest();
                attachmentRequest.fileName = fileName;
                attachmentRequest.lastKnownRevisionDate = cipher.revisionDate;
                if (attachment.key != null) {
                    attachmentRequest.key = attachment.key.encryptedString;
                }
                this.attachments2[attachment.id] = attachmentRequest;
            });
        }
    }
}

;// ../../libs/common/src/vault/models/request/cipher-with-id.request.ts

class CipherWithIdRequest extends CipherRequest {
    constructor({ cipher, encryptedFor }) {
        super({ cipher, encryptedFor });
        this.id = cipher.id;
    }
}

;// ../../libs/common/src/vault/models/request/cipher-bulk-share.request.ts

class CipherBulkShareRequest {
    constructor(ciphers, collectionIds, encryptedFor) {
        this.encryptedFor = encryptedFor;
        if (ciphers != null) {
            this.ciphers = [];
            ciphers.forEach((c) => {
                this.ciphers.push(new CipherWithIdRequest({ cipher: c, encryptedFor }));
            });
        }
        this.collectionIds = collectionIds;
    }
}

;// ../../libs/common/src/vault/models/request/cipher-bulk-update-collections.request.ts
class CipherBulkUpdateCollectionsRequest {
    constructor(organizationId, cipherIds, collectionIds, removeCollections = false) {
        this.organizationId = organizationId;
        this.cipherIds = cipherIds;
        this.collectionIds = collectionIds;
        this.removeCollections = removeCollections;
    }
}

;// ../../libs/common/src/vault/models/request/cipher-collections.request.ts
class CipherCollectionsRequest {
    constructor(collectionIds) {
        this.collectionIds = collectionIds == null ? [] : collectionIds;
    }
}

;// ../../libs/common/src/vault/models/request/cipher-create.request.ts

class CipherCreateRequest {
    constructor({ cipher, encryptedFor }) {
        this.cipher = new CipherRequest({ cipher, encryptedFor });
        this.collectionIds = cipher.collectionIds;
    }
}

;// ../../libs/common/src/vault/models/request/cipher-partial.request.ts
class CipherPartialRequest {
    constructor(cipher) {
        this.folderId = cipher.folderId;
        this.favorite = cipher.favorite;
    }
}

;// ../../libs/common/src/vault/models/request/cipher-share.request.ts

class CipherShareRequest {
    constructor({ cipher, encryptedFor }) {
        this.cipher = new CipherRequest({ cipher, encryptedFor });
        this.collectionIds = cipher.collectionIds;
    }
}

;// ../../libs/common/src/vault/services/cipher.service.ts
var cipher_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore








































const CIPHER_KEY_ENC_MIN_SERVER_VER = new external_semver_namespaceObject.SemVer("2024.2.0");
class CipherService {
    constructor(keyService, domainSettingsService, apiService, i18nService, searchService, autofillSettingsService, encryptService, cipherFileUploadService, configService, stateProvider, accountService, logService, cipherEncryptionService, messageSender, cipherSdkService) {
        this.keyService = keyService;
        this.domainSettingsService = domainSettingsService;
        this.apiService = apiService;
        this.i18nService = i18nService;
        this.searchService = searchService;
        this.autofillSettingsService = autofillSettingsService;
        this.encryptService = encryptService;
        this.cipherFileUploadService = cipherFileUploadService;
        this.configService = configService;
        this.stateProvider = stateProvider;
        this.accountService = accountService;
        this.logService = logService;
        this.cipherEncryptionService = cipherEncryptionService;
        this.messageSender = messageSender;
        this.cipherSdkService = cipherSdkService;
        this.sortedCiphersCache = new SortedCiphersCache(this.sortCiphersByLastUsed);
        /**
         * Observable that forces the `cipherViews$` observable for the given user to emit a null value.
         * Used to let subscribers of `cipherViews$` know that the decrypted ciphers have been cleared for the user and to
         * clear them from the shareReplay buffer created in perUserCache$().
         * @private
         */
        this.clearCipherViewsForUser$ = new external_rxjs_namespaceObject.Subject();
        /**
         * Observable exposing the feature flag status for using the SDK for cipher CRUD operations.
         */
        this.sdkCipherCrudEnabled$ = this.configService.getFeatureFlag$(feature_flag_enum_FeatureFlag.PM27632_SdkCipherCrudOperations);
        /**
         * Observable that emits an array of decrypted ciphers for given userId.
         * This observable will not emit until the encrypted ciphers have either been loaded from state or after sync.
         *
         * This uses the SDK for decryption, when the `PM22134SdkCipherListView` feature flag is disabled the full `cipherViews$` observable will be emitted.
         * Usage of the {@link CipherViewLike} type is recommended to ensure both `CipherView` and `CipherListView` are supported.
         */
        this.cipherListViews$ = perUserCache$((userId) => {
            let decryptStartTime;
            return this.configService.getFeatureFlag$(feature_flag_enum_FeatureFlag.PM22134SdkCipherListView).pipe((0,external_rxjs_namespaceObject.switchMap)((useSdk) => {
                if (!useSdk) {
                    return this.cipherViews$(userId);
                }
                return (0,external_rxjs_namespaceObject.combineLatest)([
                    this.encryptedCiphersState(userId).state$,
                    this.localData$(userId),
                    this.keyService.cipherDecryptionKeys$(userId, true),
                ]).pipe((0,external_rxjs_namespaceObject.filter)(([cipherDataState, _, keys]) => cipherDataState != null && keys != null), (0,external_rxjs_namespaceObject.map)(([cipherDataState, localData]) => Object.values(cipherDataState).map((cipherData) => new Cipher(cipherData, localData === null || localData === void 0 ? void 0 : localData[cipherData.id]))), (0,external_rxjs_namespaceObject.tap)(() => {
                    decryptStartTime = performance.now();
                }), (0,external_rxjs_namespaceObject.switchMap)((ciphers) => cipher_service_awaiter(this, void 0, void 0, function* () {
                    return yield this.decryptCiphersWithSdk(ciphers, userId, false);
                })), (0,external_rxjs_namespaceObject.tap)(([decrypted, failures]) => {
                    void Promise.all([
                        this.setFailedDecryptedCiphers(failures, userId),
                        this.searchService.indexCiphers(userId, decrypted),
                    ]);
                    this.logService.measure(decryptStartTime, "Vault", "CipherService", "listView decrypt complete", [["Items", decrypted.length]]);
                }), (0,external_rxjs_namespaceObject.map)(([decrypted]) => decrypted));
            }));
        }, this.clearCipherViewsForUser$);
        /**
         * Observable that emits an array of decrypted ciphers for the active user.
         * This observable will not emit until the encrypted ciphers have either been loaded from state or after sync.
         *
         * A `null` value indicates that the latest encrypted ciphers have not been decrypted yet and that
         * decryption is in progress. The latest decrypted ciphers will be emitted once decryption is complete.
         */
        this.cipherViews$ = perUserCache$((userId) => {
            return (0,external_rxjs_namespaceObject.combineLatest)([
                this.encryptedCiphersState(userId).state$,
                this.localData$(userId),
                this.keyService.cipherDecryptionKeys$(userId),
            ]).pipe((0,external_rxjs_namespaceObject.filter)(([ciphers, _, keys]) => ciphers != null && keys != null), // Skip if ciphers haven't been loaded yor synced yet
            (0,external_rxjs_namespaceObject.switchMap)(() => this.getAllDecrypted(userId)), (0,external_rxjs_namespaceObject.tap)(() => {
                this.messageSender.send("updateOverlayCiphers");
            }));
        }, this.clearCipherViewsForUser$);
        /**
         * Observable that emits an array of cipherViews that failed to decrypt. Does not emit until decryption has completed.
         *
         * An empty array indicates that all ciphers were successfully decrypted.
         */
        this.failedToDecryptCiphers$ = perUserCache$((userId) => {
            return this.failedToDecryptCiphersState(userId).state$.pipe((0,external_rxjs_namespaceObject.filter)((ciphers) => ciphers != null));
        }, this.clearCipherViewsForUser$);
    }
    localData$(userId) {
        return this.localDataState(userId).state$.pipe((0,external_rxjs_namespaceObject.map)((data) => data !== null && data !== void 0 ? data : {}));
    }
    /**
     * Observable that emits an object of encrypted ciphers for the active user.
     */
    ciphers$(userId) {
        return this.encryptedCiphersState(userId).state$.pipe((0,external_rxjs_namespaceObject.map)((ciphers) => ciphers !== null && ciphers !== void 0 ? ciphers : {}));
    }
    addEditCipherInfo$(userId) {
        return this.addEditCipherInfoState(userId).state$;
    }
    setDecryptedCipherCache(value, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            // Sometimes we might prematurely decrypt the vault and that will result in no ciphers
            // if we cache it then we may accidentally return it when it's not right, we'd rather try decryption again.
            // We still want to set null though, that is the indicator that the cache isn't valid and we should do decryption.
            if (value == null || value.length !== 0) {
                yield this.setDecryptedCiphers(value, userId);
            }
            if (this.searchService != null) {
                if (value == null) {
                    yield this.searchService.clearIndex(userId);
                }
                else {
                    void this.searchService.indexCiphers(userId, value);
                }
            }
        });
    }
    setFailedDecryptedCiphers(cipherViews, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            yield this.stateProvider.setUserState(FAILED_DECRYPTED_CIPHERS, cipherViews, userId);
        });
    }
    setDecryptedCiphers(value, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const cipherViews = {};
            value === null || value === void 0 ? void 0 : value.forEach((c) => {
                cipherViews[c.id] = c;
            });
            yield this.stateProvider.setUserState(DECRYPTED_CIPHERS, cipherViews, userId);
        });
    }
    clearCache(userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.stateProvider.activeUserId$);
            userId !== null && userId !== void 0 ? userId : (userId = activeUserId);
            yield this.clearDecryptedCiphersState(userId);
            // Force the cached cipherView$ observable(s) to emit a null value
            this.clearCipherViewsForUser$.next(userId);
        });
    }
    /**
     * Adjusts the cipher history for the given model by updating its history properties based on the original cipher.
     * @param model The cipher model to adjust.
     * @param userId The acting userId
     * @param originalCipher The original cipher to compare against. If not provided, it will be fetched from the store.
     * @private
     */
    adjustCipherHistory(model, userId, originalCipher) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            if (model.id != null) {
                if (originalCipher == null) {
                    originalCipher = yield this.get(model.id, userId);
                }
                if (originalCipher != null) {
                    yield this.updateModelfromExistingCipher(model, originalCipher, userId);
                }
                this.adjustPasswordHistoryLength(model);
            }
        });
    }
    encrypt(model_1, userId_1, keyForCipherEncryption_1, keyForCipherKeyDecryption_1) {
        return cipher_service_awaiter(this, arguments, void 0, function* (model, userId, keyForCipherEncryption, keyForCipherKeyDecryption, originalCipher = null) {
            var _a;
            yield this.adjustCipherHistory(model, userId, originalCipher);
            const sdkEncryptionEnabled = (yield this.configService.getFeatureFlag(feature_flag_enum_FeatureFlag.PM22136_SdkCipherEncryption)) &&
                keyForCipherEncryption == null && // PM-23085 - SDK encryption does not currently support custom keys (e.g. key rotation)
                keyForCipherKeyDecryption == null; // PM-23348 - Or has explicit methods for re-encrypting ciphers with different keys (e.g. move to org)
            if (sdkEncryptionEnabled) {
                return yield this.cipherEncryptionService.encrypt(model, userId);
            }
            const cipher = new Cipher();
            cipher.id = model.id;
            cipher.folderId = model.folderId;
            cipher.favorite = model.favorite;
            cipher.organizationId = model.organizationId;
            cipher.type = model.type;
            cipher.collectionIds = model.collectionIds;
            cipher.creationDate = model.creationDate;
            cipher.revisionDate = model.revisionDate;
            cipher.archivedDate = model.archivedDate;
            cipher.reprompt = model.reprompt;
            cipher.edit = model.edit;
            cipher.viewPassword = model.viewPassword;
            if (
            // prevent unprivileged users from migrating to cipher key encryption
            (model.viewPassword && (yield this.getCipherKeyEncryptionEnabled())) ||
                (originalCipher === null || originalCipher === void 0 ? void 0 : originalCipher.key)) {
                cipher.key = (_a = originalCipher === null || originalCipher === void 0 ? void 0 : originalCipher.key) !== null && _a !== void 0 ? _a : null;
                const userOrOrgKey = yield this.getKeyForCipherKeyDecryption(cipher, userId);
                // The keyForEncryption is only used for encrypting the cipher key, not the cipher itself, since cipher key encryption is enabled.
                // If the caller has provided a key for cipher key encryption, use it. Otherwise, use the user or org key.
                keyForCipherEncryption || (keyForCipherEncryption = userOrOrgKey);
                // If the caller has provided a key for cipher key decryption, use it. Otherwise, use the user or org key.
                keyForCipherKeyDecryption || (keyForCipherKeyDecryption = userOrOrgKey);
                return {
                    cipher: yield this.encryptCipherWithCipherKey(model, cipher, keyForCipherEncryption, keyForCipherKeyDecryption),
                    encryptedFor: userId,
                };
            }
            else {
                keyForCipherEncryption || (keyForCipherEncryption = yield this.getKeyForCipherKeyDecryption(cipher, userId));
                // We want to ensure that the cipher key is null if cipher key encryption is disabled
                // so that decryption uses the proper key.
                cipher.key = null;
                return {
                    cipher: yield this.encryptCipher(model, cipher, keyForCipherEncryption),
                    encryptedFor: userId,
                };
            }
        });
    }
    encryptMany(models, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const sdkEncryptionEnabled = yield this.configService.getFeatureFlag(feature_flag_enum_FeatureFlag.PM22136_SdkCipherEncryption);
            if (sdkEncryptionEnabled) {
                return yield this.cipherEncryptionService.encryptMany(models, userId);
            }
            // Fallback to sequential encryption if SDK disabled
            const results = [];
            for (const model of models) {
                const result = yield this.encrypt(model, userId);
                results.push(result);
            }
            return results;
        });
    }
    encryptAttachments(attachmentsModel, key) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            if (attachmentsModel == null || attachmentsModel.length === 0) {
                return null;
            }
            const promises = [];
            const encAttachments = [];
            attachmentsModel.forEach((model) => cipher_service_awaiter(this, void 0, void 0, function* () {
                const attachment = new Attachment();
                attachment.id = model.id;
                attachment.size = model.size;
                attachment.sizeName = model.sizeName;
                attachment.url = model.url;
                const promise = this.encryptObjProperty(model, attachment, { fileName: null }, key).then(() => cipher_service_awaiter(this, void 0, void 0, function* () {
                    if (model.key != null) {
                        attachment.key = yield this.encryptService.wrapSymmetricKey(model.key, key);
                    }
                    encAttachments.push(attachment);
                }));
                promises.push(promise);
            }));
            yield Promise.all(promises);
            return encAttachments;
        });
    }
    encryptFields(fieldsModel, key) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            if (!fieldsModel || !fieldsModel.length) {
                return null;
            }
            const self = this;
            const encFields = [];
            yield fieldsModel.reduce((promise, field) => cipher_service_awaiter(this, void 0, void 0, function* () {
                yield promise;
                const encField = yield self.encryptField(field, key);
                encFields.push(encField);
            }), Promise.resolve());
            return encFields;
        });
    }
    encryptField(fieldModel, key) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const field = new Field();
            field.type = fieldModel.type;
            field.linkedId = fieldModel.linkedId;
            // normalize boolean type field values
            if (fieldModel.type === FieldType.Boolean && fieldModel.value !== "true") {
                fieldModel.value = "false";
            }
            yield this.encryptObjProperty(fieldModel, field, { name: null, value: null }, key);
            return field;
        });
    }
    encryptPasswordHistories(phModels, key) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            if (!phModels || !phModels.length) {
                return null;
            }
            const self = this;
            const encPhs = [];
            yield phModels.reduce((promise, ph) => cipher_service_awaiter(this, void 0, void 0, function* () {
                yield promise;
                const encPh = yield self.encryptPasswordHistory(ph, key);
                encPhs.push(encPh);
            }), Promise.resolve());
            return encPhs;
        });
    }
    encryptPasswordHistory(phModel, key) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const ph = new Password();
            ph.lastUsedDate = phModel.lastUsedDate;
            yield this.encryptObjProperty(phModel, ph, { password: null }, key);
            return ph;
        });
    }
    get(id, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const ciphers = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.ciphers$(userId));
            // eslint-disable-next-line
            if (ciphers == null || !ciphers.hasOwnProperty(id)) {
                return null;
            }
            const localData = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.localData$(userId));
            const cipherId = id;
            return new Cipher(ciphers[cipherId], localData ? localData[cipherId] : null);
        });
    }
    getAll(userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const localData = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.localData$(userId));
            const ciphers = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.ciphers$(userId));
            const response = [];
            for (const id in ciphers) {
                // eslint-disable-next-line
                if (ciphers.hasOwnProperty(id)) {
                    const cipherId = id;
                    response.push(new Cipher(ciphers[cipherId], localData ? localData[cipherId] : null));
                }
            }
            return response;
        });
    }
    /**
     * Decrypts all ciphers for the active user and caches them in memory. If the ciphers have already been decrypted and
     * cached, the cached ciphers are returned.
     * @deprecated Use `cipherViews$` observable instead
     */
    getAllDecrypted(userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const useSdk = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkCipherCrudEnabled$);
            if (useSdk) {
                return this.getAllDecryptedUsingSdk(userId);
            }
            const decCiphers = yield this.getDecryptedCiphers(userId);
            if (decCiphers != null && decCiphers.length !== 0) {
                yield this.reindexCiphers(userId);
                return decCiphers;
            }
            const decrypted = yield this.decryptCiphers(yield this.getAll(userId), userId);
            // We failed to decrypt, return empty array but do not cache
            if (decrypted == null) {
                return [];
            }
            const [newDecCiphers, failedCiphers] = decrypted;
            yield this.setDecryptedCipherCache(newDecCiphers, userId);
            yield this.setFailedDecryptedCiphers(failedCiphers, userId);
            return newDecCiphers;
        });
    }
    getAllDecryptedUsingSdk(userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            try {
                const result = yield this.cipherSdkService.getAllDecrypted(userId);
                yield this.setDecryptedCipherCache(result.successes, userId);
                yield this.setFailedDecryptedCiphers(result.failures, userId);
                return result.successes;
            }
            catch (_a) {
                // Return empty array on error to maintain existing behavior
                return [];
            }
        });
    }
    getDecryptedCiphers(userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            return Object.values(yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.decryptedCiphersState(userId).state$.pipe((0,external_rxjs_namespaceObject.map)((c) => c !== null && c !== void 0 ? c : {}))));
        });
    }
    /**
     * Decrypts the provided ciphers using the provided user's keys.
     * @param ciphers
     * @param userId
     * @returns Two cipher arrays, the first containing successfully decrypted ciphers and the second containing ciphers that failed to decrypt.
     * @private
     */
    decryptCiphers(ciphers, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            if (ciphers.length === 0) {
                return [[], []];
            }
            if (yield this.configService.getFeatureFlag(feature_flag_enum_FeatureFlag.PM19941MigrateCipherDomainToSdk)) {
                const decryptStartTime = performance.now();
                const result = yield this.decryptCiphersWithSdk(ciphers, userId, true);
                this.logService.measure(decryptStartTime, "Vault", "CipherService", "decrypt complete", [
                    ["Items", ciphers.length],
                ]);
                return result;
            }
            const keys = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.cipherDecryptionKeys$(userId));
            if (keys == null || (keys.userKey == null && Object.keys(keys.orgKeys).length === 0)) {
                // return early if there are no keys to decrypt with
                return null;
            }
            // Group ciphers by orgId or under 'null' for the user's ciphers
            const grouped = ciphers.reduce((agg, c) => {
                var _a;
                var _b;
                (_a = agg[_b = c.organizationId]) !== null && _a !== void 0 ? _a : (agg[_b] = []);
                agg[c.organizationId].push(c);
                return agg;
            }, {});
            const decryptStartTime = performance.now();
            const allCipherViews = (yield Promise.all(Object.entries(grouped).map((_a) => cipher_service_awaiter(this, [_a], void 0, function* ([orgId, groupedCiphers]) {
                var _b;
                const key = (_b = keys.orgKeys[orgId]) !== null && _b !== void 0 ? _b : keys.userKey;
                return yield Promise.all(groupedCiphers.map((cipher) => cipher_service_awaiter(this, void 0, void 0, function* () {
                    return yield cipher.decrypt(key);
                })));
            }))))
                .flat()
                .sort(this.getLocaleSortingFunction());
            this.logService.measure(decryptStartTime, "Vault", "CipherService", "decrypt complete", [
                ["Items", ciphers.length],
            ]);
            // Split ciphers into two arrays, one for successfully decrypted ciphers and one for ciphers that failed to decrypt
            return allCipherViews.reduce((acc, c) => {
                if (c.decryptionFailure) {
                    acc[1].push(c);
                }
                else {
                    acc[0].push(c);
                }
                return acc;
            }, [[], []]);
        });
    }
    /**
     * Decrypts a cipher using either the SDK or the legacy method based on the feature flag.
     * @param cipher The cipher to decrypt.
     * @param userId The user ID to use for decryption.
     * @returns A promise that resolves to the decrypted cipher view.
     */
    decrypt(cipher, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            if (yield this.configService.getFeatureFlag(feature_flag_enum_FeatureFlag.PM19941MigrateCipherDomainToSdk)) {
                return yield this.cipherEncryptionService.decrypt(cipher, userId);
            }
            else {
                const encKey = yield this.getKeyForCipherKeyDecryption(cipher, userId);
                return yield cipher.decrypt(encKey);
            }
        });
    }
    reindexCiphers(userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            var _a;
            const reindexRequired = this.searchService != null &&
                ((_a = (yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.searchService.indexedEntityId$(userId)))) !== null && _a !== void 0 ? _a : userId) !== userId;
            if (reindexRequired) {
                yield this.searchService.indexCiphers(userId, yield this.getDecryptedCiphers(userId), userId);
            }
        });
    }
    getAllDecryptedForGrouping(groupingId_1, userId_1) {
        return cipher_service_awaiter(this, arguments, void 0, function* (groupingId, userId, folder = true) {
            const ciphers = yield this.getAllDecrypted(userId);
            return ciphers.filter((cipher) => {
                if (cipher.isDeleted) {
                    return false;
                }
                if (folder && cipher.folderId === groupingId) {
                    return true;
                }
                else if (!folder &&
                    cipher.collectionIds != null &&
                    cipher.collectionIds.indexOf(groupingId) > -1) {
                    return true;
                }
                return false;
            });
        });
    }
    getAllDecryptedForUrl(url_1, userId_1, includeOtherTypes_1) {
        return cipher_service_awaiter(this, arguments, void 0, function* (url, userId, includeOtherTypes, defaultMatch = null, overrideNeverMatchStrategy) {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.cipherViews$(userId).pipe((0,external_rxjs_namespaceObject.filter)((c) => c != null), (0,external_rxjs_namespaceObject.switchMap)((ciphers) => cipher_service_awaiter(this, void 0, void 0, function* () {
                return yield this.filterCiphersForUrl(ciphers, url, includeOtherTypes, defaultMatch, overrideNeverMatchStrategy);
            }))));
        });
    }
    getAllDecryptedForIds(userId, ids) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            return (0,external_rxjs_namespaceObject.firstValueFrom)(this.cipherViews$(userId).pipe((0,external_rxjs_namespaceObject.filter)((ciphers) => ciphers != null), (0,external_rxjs_namespaceObject.map)((ciphers) => ciphers.filter((cipher) => ids.includes(cipher.id)))));
        });
    }
    filterCiphersForUrl(ciphers_1, url_1, includeOtherTypes_1) {
        return cipher_service_awaiter(this, arguments, void 0, function* (ciphers, url, includeOtherTypes, defaultMatch = null, overrideNeverMatchStrategy) {
            if (url == null && includeOtherTypes == null) {
                return [];
            }
            const equivalentDomains = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.domainSettingsService.getUrlEquivalentDomains(url));
            defaultMatch !== null && defaultMatch !== void 0 ? defaultMatch : (defaultMatch = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.domainSettingsService.resolvedDefaultUriMatchStrategy$));
            return ciphers.filter((cipher) => {
                const type = CipherViewLikeUtils.getType(cipher);
                const login = CipherViewLikeUtils.getLogin(cipher);
                const cipherIsLogin = login !== null;
                if (CipherViewLikeUtils.isDeleted(cipher)) {
                    return false;
                }
                if (CipherViewLikeUtils.isArchived(cipher)) {
                    return false;
                }
                if (Array.isArray(includeOtherTypes) && includeOtherTypes.includes(type) && !cipherIsLogin) {
                    return true;
                }
                if (cipherIsLogin) {
                    return CipherViewLikeUtils.matchesUri(cipher, url, equivalentDomains, defaultMatch, overrideNeverMatchStrategy);
                }
                return false;
            });
        });
    }
    getAllDecryptedCiphersOfType(type, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const ciphers = yield this.getAllDecrypted(userId);
            return ciphers
                .filter((cipher) => cipher.deletedDate == null && !cipher.isArchived && type.includes(cipher.type))
                .sort((a, b) => this.sortCiphersByLastUsedThenName(a, b));
        });
    }
    getAllFromApiForOrganization(organizationId, includeMemberItems) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const useSdk = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkCipherCrudEnabled$);
            if (useSdk) {
                return this.getAllFromApiForOrganizationUsingSdk(organizationId, includeMemberItems !== null && includeMemberItems !== void 0 ? includeMemberItems : false);
            }
            const response = yield this.apiService.getCiphersOrganization(organizationId, includeMemberItems);
            return yield this.decryptOrganizationCiphersResponse(response, organizationId);
        });
    }
    getAllFromApiForOrganizationUsingSdk(organizationId, includeMemberItems) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.map)((a) => a === null || a === void 0 ? void 0 : a.id)));
            if (!userId) {
                throw new Error("User ID is required");
            }
            try {
                const [ciphers] = yield this.cipherSdkService.getAllFromApiForOrganization(organizationId, userId, includeMemberItems);
                const [cipherViews] = yield this.cipherEncryptionService.decryptManyLegacy(ciphers, userId);
                // Sort by locale (matching existing behavior)
                cipherViews.sort(this.getLocaleSortingFunction());
                return cipherViews;
            }
            catch (_a) {
                // Return empty array on error to maintain existing behavior
                return [];
            }
        });
    }
    getManyFromApiForOrganization(organizationId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("GET", "/ciphers/organization-details/assigned?organizationId=" + organizationId, null, true, true);
            const response = new ListResponse(r, cipher_response_CipherResponse);
            return this.decryptOrganizationCiphersResponse(response, organizationId);
        });
    }
    decryptOrganizationCiphersResponse(response, organizationId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            if ((response === null || response === void 0 ? void 0 : response.data) == null || response.data.length < 1) {
                return [];
            }
            const ciphers = response.data.map((cr) => new Cipher(new CipherData(cr)));
            const key = yield this.keyService.getOrgKey(organizationId);
            const decCiphers = yield Promise.all(ciphers.map((cipher) => cipher_service_awaiter(this, void 0, void 0, function* () {
                return yield cipher.decrypt(key);
            })));
            decCiphers.sort(this.getLocaleSortingFunction());
            return decCiphers;
        });
    }
    getLastUsedForUrl(url_1, userId_1) {
        return cipher_service_awaiter(this, arguments, void 0, function* (url, userId, autofillOnPageLoad = false) {
            return this.getCipherForUrl(url, userId, true, false, autofillOnPageLoad);
        });
    }
    getLastLaunchedForUrl(url_1, userId_1) {
        return cipher_service_awaiter(this, arguments, void 0, function* (url, userId, autofillOnPageLoad = false) {
            return this.getCipherForUrl(url, userId, false, true, autofillOnPageLoad);
        });
    }
    getNextCipherForUrl(url, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            return this.getCipherForUrl(url, userId, false, false, false);
        });
    }
    getNextCardCipher(userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const cacheKey = "cardCiphers";
            if (!this.sortedCiphersCache.isCached(cacheKey)) {
                const ciphers = yield this.getAllDecryptedCiphersOfType([CipherType.Card], userId);
                if (!(ciphers === null || ciphers === void 0 ? void 0 : ciphers.length)) {
                    return null;
                }
                this.sortedCiphersCache.addCiphers(cacheKey, ciphers);
            }
            return this.sortedCiphersCache.getNext(cacheKey);
        });
    }
    getNextIdentityCipher(userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const cacheKey = "identityCiphers";
            if (!this.sortedCiphersCache.isCached(cacheKey)) {
                const ciphers = yield this.getAllDecryptedCiphersOfType([CipherType.Identity], userId);
                if (!(ciphers === null || ciphers === void 0 ? void 0 : ciphers.length)) {
                    return null;
                }
                this.sortedCiphersCache.addCiphers(cacheKey, ciphers);
            }
            return this.sortedCiphersCache.getNext(cacheKey);
        });
    }
    updateLastUsedIndexForUrl(url) {
        this.sortedCiphersCache.updateLastUsedIndex(url);
    }
    updateLastUsedDate(id, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            let ciphersLocalData = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.localData$(userId));
            if (!ciphersLocalData) {
                ciphersLocalData = {};
            }
            const cipherId = id;
            if (ciphersLocalData[cipherId]) {
                ciphersLocalData[cipherId].lastUsedDate = new Date().getTime();
            }
            else {
                ciphersLocalData[cipherId] = { lastUsedDate: new Date().getTime() };
            }
            yield this.localDataState(userId).update(() => ciphersLocalData);
            const decryptedCipherCache = yield this.getDecryptedCiphers(userId);
            if (!decryptedCipherCache) {
                return;
            }
            for (let i = 0; i < decryptedCipherCache.length; i++) {
                const cached = decryptedCipherCache[i];
                if (cached.id === id) {
                    cached.localData = ciphersLocalData[id];
                    break;
                }
            }
            yield this.setDecryptedCiphers(decryptedCipherCache, userId);
        });
    }
    updateLastLaunchedDate(id, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            let ciphersLocalData = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.localData$(userId));
            if (!ciphersLocalData) {
                ciphersLocalData = {};
            }
            const currentTime = new Date().getTime();
            ciphersLocalData[id] = { lastLaunched: currentTime, lastUsedDate: currentTime };
            yield this.localDataState(userId).update(() => ciphersLocalData);
            const decryptedCipherCache = yield this.getDecryptedCiphers(userId);
            if (!decryptedCipherCache) {
                return;
            }
            for (let i = 0; i < decryptedCipherCache.length; i++) {
                const cached = decryptedCipherCache[i];
                if (cached.id === id) {
                    cached.localData = ciphersLocalData[id];
                    break;
                }
            }
            yield this.setDecryptedCiphers(decryptedCipherCache, userId);
        });
    }
    saveNeverDomain(domain) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            if (domain == null) {
                return;
            }
            let domains = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.domainSettingsService.neverDomains$);
            if (!domains) {
                domains = {};
            }
            domains[domain] = null;
            yield this.domainSettingsService.setNeverDomains(domains);
        });
    }
    createWithServer(cipherView, userId, orgAdmin) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const useSdk = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkCipherCrudEnabled$);
            if (useSdk) {
                return ((yield this.createWithServerUsingSdk(cipherView, userId, orgAdmin)) || new CipherView());
            }
            const encrypted = yield this.encrypt(cipherView, userId);
            const result = yield this.createWithServerLegacy(encrypted, orgAdmin);
            return yield this.decrypt(result, userId);
        });
    }
    createWithServerUsingSdk(cipherView, userId, orgAdmin) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            // Clear the cache before creating the cipher. The SDK internally updates the encrypted storage
            // but the timing of the storage emitting the new values differs across platforms. Clearing the cache after
            // `createWithServer` can cause race conditions where the cache is cleared after the
            // encrypted storage has already been updated and thus downstream consumers not getting updated data.
            yield this.clearCache(userId);
            const resultCipherView = yield this.cipherSdkService.createWithServer(cipherView, userId, orgAdmin);
            return resultCipherView;
        });
    }
    createWithServerLegacy(_a, orgAdmin_1) {
        return cipher_service_awaiter(this, arguments, void 0, function* ({ cipher, encryptedFor }, orgAdmin) {
            let response;
            if (orgAdmin && cipher.organizationId != null) {
                const request = new CipherCreateRequest({ cipher, encryptedFor });
                response = yield this.apiService.postCipherAdmin(request);
                const data = new CipherData(response, cipher.collectionIds);
                return new Cipher(data);
            }
            else if (cipher.collectionIds != null && cipher.collectionIds.length > 0) {
                const request = new CipherCreateRequest({ cipher, encryptedFor });
                response = yield this.apiService.postCipherCreate(request);
            }
            else {
                const request = new CipherRequest({ cipher, encryptedFor });
                response = yield this.apiService.postCipher(request);
            }
            cipher.id = response.id;
            const data = new CipherData(response, cipher.collectionIds);
            const updated = yield this.upsert(data);
            // No local data for new ciphers
            return new Cipher(updated[cipher.id]);
        });
    }
    updateWithServer(cipherView, userId, originalCipherView, orgAdmin) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const useSdk = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkCipherCrudEnabled$);
            if (useSdk) {
                return yield this.updateWithServerUsingSdk(cipherView, userId, originalCipherView, orgAdmin);
            }
            const encrypted = yield this.encrypt(cipherView, userId);
            const updatedCipher = yield this.updateWithServerLegacy(encrypted, orgAdmin);
            const updatedCipherView = yield this.decrypt(updatedCipher, userId);
            return updatedCipherView;
        });
    }
    updateWithServerUsingSdk(cipher, userId, originalCipherView, orgAdmin) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            // Clear the cache before updating the cipher. The SDK internally updates the encrypted storage
            // but the timing of the storage emitting the new values differs across platforms. Clearing the cache after
            // `updateWithServer` can cause race conditions where the cache is cleared after the
            // encrypted storage has already been updated and thus downstream consumers not getting updated data.
            yield this.clearCache(userId);
            const resultCipherView = yield this.cipherSdkService.updateWithServer(cipher, userId, originalCipherView, orgAdmin);
            return resultCipherView;
        });
    }
    updateWithServerLegacy(_a, orgAdmin_1) {
        return cipher_service_awaiter(this, arguments, void 0, function* ({ cipher, encryptedFor }, orgAdmin) {
            let response;
            if (orgAdmin) {
                const request = new CipherRequest({ cipher, encryptedFor });
                response = yield this.apiService.putCipherAdmin(cipher.id, request);
                const data = new CipherData(response, cipher.collectionIds);
                return new Cipher(data, cipher.localData);
            }
            else if (cipher.edit) {
                const request = new CipherRequest({ cipher, encryptedFor });
                response = yield this.apiService.putCipher(cipher.id, request);
            }
            else {
                const request = new CipherPartialRequest(cipher);
                response = yield this.apiService.putPartialCipher(cipher.id, request);
            }
            const data = new CipherData(response, cipher.collectionIds);
            const updated = yield this.upsert(data);
            // updating with server does not change local data
            return new Cipher(updated[cipher.id], cipher.localData);
        });
    }
    shareWithServer(cipher, organizationId, collectionIds, userId, originalCipher) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const sdkCipherEncryptionEnabled = yield this.configService.getFeatureFlag(feature_flag_enum_FeatureFlag.PM22136_SdkCipherEncryption);
            yield this.adjustCipherHistory(cipher, userId, originalCipher);
            let encCipher;
            if (sdkCipherEncryptionEnabled) {
                // The SDK does not expect the cipher to already have an organizationId. It will result in the wrong
                // cipher encryption key being used during the move to organization operation.
                if (cipher.organizationId != null) {
                    throw new Error("Cipher is already associated with an organization.");
                }
                encCipher = yield this.cipherEncryptionService.moveToOrganization(cipher, organizationId, userId);
                encCipher.cipher.collectionIds = collectionIds;
            }
            else {
                // This old attachment logic is safe to remove after it is replaced in PM-22750; which will require fixing
                // the attachment before sharing.
                const attachmentPromises = [];
                if (cipher.attachments != null) {
                    cipher.attachments.forEach((attachment) => {
                        if (attachment.key == null) {
                            attachmentPromises.push(this.shareAttachmentWithServer(attachment, cipher.id, organizationId, cipher.revisionDate));
                        }
                    });
                }
                yield Promise.all(attachmentPromises);
                cipher.organizationId = organizationId;
                cipher.collectionIds = collectionIds;
                encCipher = yield this.encryptSharedCipher(cipher, userId);
            }
            const request = new CipherShareRequest(encCipher);
            const response = yield this.apiService.putShareCipher(cipher.id, request);
            const data = new CipherData(response, collectionIds);
            yield this.upsert(data);
            return new Cipher(data, cipher.localData);
        });
    }
    shareManyWithServer(ciphers, organizationId, collectionIds, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const sdkCipherEncryptionEnabled = yield this.configService.getFeatureFlag(feature_flag_enum_FeatureFlag.PM22136_SdkCipherEncryption);
            const promises = [];
            const encCiphers = [];
            for (const cipher of ciphers) {
                if (sdkCipherEncryptionEnabled) {
                    // The SDK does not expect the cipher to already have an organizationId. It will result in the wrong
                    // cipher encryption key being used during the move to organization operation.
                    if (cipher.organizationId != null) {
                        throw new Error("Cipher is already associated with an organization.");
                    }
                    promises.push(this.cipherEncryptionService
                        .moveToOrganization(cipher, organizationId, userId)
                        .then((encCipher) => {
                        encCipher.cipher.collectionIds = collectionIds;
                        encCiphers.push(encCipher.cipher);
                    }));
                }
                else {
                    cipher.organizationId = organizationId;
                    cipher.collectionIds = collectionIds;
                    promises.push(this.encryptSharedCipher(cipher, userId).then((c) => {
                        encCiphers.push(c.cipher);
                    }));
                }
            }
            yield Promise.all(promises);
            const request = new CipherBulkShareRequest(encCiphers, collectionIds, userId);
            try {
                const response = yield this.apiService.putShareCiphers(request);
                const responseMap = new Map(response.data.map((r) => [r.id, r]));
                encCiphers.forEach((cipher) => {
                    const matchingCipher = responseMap.get(cipher.id);
                    if (matchingCipher) {
                        cipher.revisionDate = new Date(matchingCipher.revisionDate);
                    }
                });
                yield this.upsert(encCiphers.map((c) => c.toCipherData()));
            }
            catch (e) {
                for (const cipher of ciphers) {
                    cipher.organizationId = null;
                    cipher.collectionIds = null;
                }
                throw e;
            }
        });
    }
    saveAttachmentWithServer(cipher, unencryptedFile, userId, admin = false, options) {
        return new Promise((resolve, reject) => {
            const reader = new FileReader();
            reader.readAsArrayBuffer(unencryptedFile);
            reader.onload = (evt) => cipher_service_awaiter(this, void 0, void 0, function* () {
                try {
                    const cData = yield this.saveAttachmentRawWithServer(cipher, unencryptedFile.name, evt.target.result, userId, admin, options);
                    resolve(cData);
                }
                catch (e) {
                    reject(e);
                }
            });
            reader.onerror = () => {
                reject("Error reading file.");
            };
        });
    }
    saveAttachmentRawWithServer(cipher_1, filename_1, data_1, userId_1) {
        return cipher_service_awaiter(this, arguments, void 0, function* (cipher, filename, data, userId, admin = false, options) {
            // The organization's symmetric key or the user's user key
            const vaultKey = yield this.getKeyForCipherKeyDecryption(cipher, userId);
            const cipherKeyOrVaultKey = cipher.key != null
                ? (yield this.encryptService.unwrapSymmetricKey(cipher.key, vaultKey))
                : vaultKey;
            const encFileName = yield this.encryptService.encryptString(filename, cipherKeyOrVaultKey);
            const attachmentKey = yield this.keyService.makeDataEncKey(cipherKeyOrVaultKey);
            const encData = yield this.encryptService.encryptFileData(new Uint8Array(data), attachmentKey[0]);
            const response = yield this.cipherFileUploadService.upload(cipher, encFileName, encData, admin, attachmentKey, options);
            const cData = new CipherData(response, cipher.collectionIds);
            if (!admin) {
                yield this.upsert(cData);
            }
            return new Cipher(cData);
        });
    }
    saveCollectionsWithServer(cipher, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const request = new CipherCollectionsRequest(cipher.collectionIds);
            const response = yield this.apiService.putCipherCollections(cipher.id, request);
            // The response will now check for an unavailable value. This value determines whether
            // the user still has Can Manage access to the item after updating.
            if (response.unavailable) {
                yield this.delete(cipher.id, userId);
                return;
            }
            const data = new CipherData(response.cipher);
            const updated = yield this.upsert(data);
            return new Cipher(updated[cipher.id], cipher.localData);
        });
    }
    saveCollectionsWithServerAdmin(cipher) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const request = new CipherCollectionsRequest(cipher.collectionIds);
            const response = yield this.apiService.putCipherCollectionsAdmin(cipher.id, request);
            // The response will be incomplete with several properties missing values
            // We will assign those properties values so the SDK decryption can complete
            const completedResponse = new cipher_response_CipherResponse(response);
            completedResponse.edit = true;
            completedResponse.viewPassword = true;
            completedResponse.favorite = false;
            const data = new CipherData(completedResponse);
            return new Cipher(data);
        });
    }
    /**
     * Bulk update collections for many ciphers with the server
     * @param orgId
     * @param cipherIds
     * @param collectionIds
     * @param removeCollections - If true, the collectionIds will be removed from the ciphers, otherwise they will be added
     */
    bulkUpdateCollectionsWithServer(orgId_1, userId_1, cipherIds_1, collectionIds_1) {
        return cipher_service_awaiter(this, arguments, void 0, function* (orgId, userId, cipherIds, collectionIds, removeCollections = false) {
            var _a, _b;
            const request = new CipherBulkUpdateCollectionsRequest(orgId, cipherIds, collectionIds, removeCollections);
            yield this.apiService.send("POST", "/ciphers/bulk-collections", request, true, false);
            // Update the local state
            const ciphers = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.ciphers$(userId));
            for (const id of cipherIds) {
                const cipher = ciphers[id];
                if (cipher) {
                    if (removeCollections) {
                        cipher.collectionIds = (_a = cipher.collectionIds) === null || _a === void 0 ? void 0 : _a.filter((cid) => !collectionIds.includes(cid));
                    }
                    else {
                        // Append to the collectionIds if it's not already there
                        cipher.collectionIds = [...new Set([...((_b = cipher.collectionIds) !== null && _b !== void 0 ? _b : []), ...collectionIds])];
                    }
                }
            }
            yield this.clearCache();
            yield this.encryptedCiphersState(userId).update(() => ciphers);
        });
    }
    upsert(cipher, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const ciphers = cipher instanceof CipherData ? [cipher] : cipher;
            const res = yield this.updateEncryptedCipherState((current) => {
                ciphers.forEach((c) => (current[c.id] = c));
                return current;
            }, userId);
            // Some state storage providers (e.g. Electron) don't update the state immediately, wait for next tick
            // Otherwise, subscribers to cipherViews$ can get stale data
            yield new Promise((resolve) => setTimeout(resolve, 0));
            return res;
        });
    }
    replace(ciphers, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            var _a;
            const current = (_a = (yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.encryptedCiphersState(userId).state$))) !== null && _a !== void 0 ? _a : {};
            // The extension relies on chrome.storage.StorageArea.onChanged to detect updates.
            // If stored and provided data are identical, this event doesn’t fire and the ciphers$
            // observable won’t emit a new value. In this case we can skip the update to avoid calling
            // clearCache and causing an empty state.
            // If the current state is empty (eg. for new users), we still want to perform the update to ensure
            // we trigger an emission as many subscribers rely on it during initialization.
            if (Object.keys(current).length > 0 && JSON.stringify(current) === JSON.stringify(ciphers)) {
                return;
            }
            yield this.updateEncryptedCipherState(() => ciphers, userId);
        });
    }
    /**
     * Updates ciphers for the currently active user. Inactive users can only clear all ciphers, for now.
     * @param update update callback for encrypted cipher data
     * @returns
     */
    updateEncryptedCipherState(update_1) {
        return cipher_service_awaiter(this, arguments, void 0, function* (update, userId = null) {
            userId || (userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.stateProvider.activeUserId$));
            yield this.clearCache(userId);
            const updatedCiphers = yield this.stateProvider
                .getUser(userId, ENCRYPTED_CIPHERS)
                .update((current) => {
                const result = update(current !== null && current !== void 0 ? current : {});
                return result;
            });
            // Some state storage providers (e.g. Electron) don't update the state immediately, wait for next tick
            // Otherwise, subscribers to cipherViews$ can get stale data
            yield new Promise((resolve) => setTimeout(resolve, 0));
            return updatedCiphers;
        });
    }
    clear(userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            userId !== null && userId !== void 0 ? userId : (userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.stateProvider.activeUserId$));
            yield this.clearEncryptedCiphersState(userId);
            yield this.clearCache(userId);
        });
    }
    moveManyWithServer(ids, folderId, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            yield this.apiService.putMoveCiphers(new CipherBulkMoveRequest(ids, folderId));
            let ciphers = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.ciphers$(userId));
            if (ciphers == null) {
                ciphers = {};
            }
            ids.forEach((id) => {
                // eslint-disable-next-line
                if (ciphers.hasOwnProperty(id)) {
                    ciphers[id].folderId = folderId;
                }
            });
            yield this.clearCache();
            yield this.encryptedCiphersState(userId).update(() => ciphers);
        });
    }
    delete(id, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const ciphers = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.ciphers$(userId));
            if (ciphers == null) {
                return;
            }
            if (typeof id === "string") {
                const cipherId = id;
                if (ciphers[cipherId] == null) {
                    return;
                }
                delete ciphers[cipherId];
            }
            else {
                id.forEach((i) => {
                    delete ciphers[i];
                });
            }
            yield this.clearCache();
            yield this.encryptedCiphersState(userId).update(() => ciphers);
        });
    }
    deleteWithServer(id_1, userId_1) {
        return cipher_service_awaiter(this, arguments, void 0, function* (id, userId, asAdmin = false) {
            const useSdk = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkCipherCrudEnabled$);
            if (useSdk) {
                yield this.clearCache(userId);
                yield this.cipherSdkService.deleteWithServer(id, userId, asAdmin);
                return;
            }
            if (asAdmin) {
                yield this.apiService.deleteCipherAdmin(id);
            }
            else {
                yield this.apiService.deleteCipher(id);
            }
            yield this.delete(id, userId);
        });
    }
    deleteManyWithServer(ids_1, userId_1) {
        return cipher_service_awaiter(this, arguments, void 0, function* (ids, userId, asAdmin = false, orgId) {
            const useSdk = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkCipherCrudEnabled$);
            if (useSdk) {
                yield this.clearCache(userId);
                yield this.cipherSdkService.deleteManyWithServer(ids, userId, asAdmin, orgId);
                return;
            }
            const request = new CipherBulkDeleteRequest(ids, orgId);
            if (asAdmin) {
                yield this.apiService.deleteManyCiphersAdmin(request);
            }
            else {
                yield this.apiService.deleteManyCiphers(request);
            }
            yield this.delete(ids, userId);
        });
    }
    deleteAttachment(id, revisionDate, attachmentId, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            let ciphers = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.ciphers$(userId));
            const cipherId = id;
            // eslint-disable-next-line
            if (ciphers == null || !ciphers.hasOwnProperty(id) || ciphers[cipherId].attachments == null) {
                return;
            }
            for (let i = 0; i < ciphers[cipherId].attachments.length; i++) {
                if (ciphers[cipherId].attachments[i].id === attachmentId) {
                    ciphers[cipherId].attachments.splice(i, 1);
                }
            }
            // Deleting the cipher updates the revision date on the server,
            // Update the stored `revisionDate` to match
            ciphers[cipherId].revisionDate = revisionDate;
            yield this.clearCache();
            yield this.encryptedCiphersState(userId).update(() => {
                if (ciphers == null) {
                    ciphers = {};
                }
                return ciphers;
            });
            return ciphers[cipherId];
        });
    }
    deleteAttachmentWithServer(id_1, attachmentId_1, userId_1) {
        return cipher_service_awaiter(this, arguments, void 0, function* (id, attachmentId, userId, admin = false) {
            let response;
            try {
                response = admin
                    ? yield this.apiService.deleteCipherAttachmentAdmin(id, attachmentId)
                    : yield this.apiService.deleteCipherAttachment(id, attachmentId);
            }
            catch (e) {
                return Promise.reject(e.getSingleMessage());
            }
            const cipherData = new CipherData(response.cipher);
            return yield this.deleteAttachment(id, cipherData.revisionDate, attachmentId, userId);
        });
    }
    sortCiphersByLastUsed(a, b) {
        const aLastUsed = a.localData && a.localData.lastUsedDate ? a.localData.lastUsedDate : null;
        const bLastUsed = b.localData && b.localData.lastUsedDate ? b.localData.lastUsedDate : null;
        const bothNotNull = aLastUsed != null && bLastUsed != null;
        if (bothNotNull && aLastUsed < bLastUsed) {
            return 1;
        }
        if (aLastUsed != null && bLastUsed == null) {
            return -1;
        }
        if (bothNotNull && aLastUsed > bLastUsed) {
            return -1;
        }
        if (bLastUsed != null && aLastUsed == null) {
            return 1;
        }
        return 0;
    }
    sortCiphersByLastUsedThenName(a, b) {
        const result = this.sortCiphersByLastUsed(a, b);
        if (result !== 0) {
            return result;
        }
        return this.getLocaleSortingFunction()(a, b);
    }
    getLocaleSortingFunction() {
        return (a, b) => {
            let aName = a.name;
            let bName = b.name;
            if (aName == null && bName != null) {
                return -1;
            }
            if (aName != null && bName == null) {
                return 1;
            }
            if (aName == null && bName == null) {
                return 0;
            }
            const result = this.i18nService.collator
                ? this.i18nService.collator.compare(aName, bName)
                : aName.localeCompare(bName);
            const aType = CipherViewLikeUtils.getType(a);
            const bType = CipherViewLikeUtils.getType(b);
            if (result !== 0 || aType !== CipherType.Login || bType !== CipherType.Login) {
                return result;
            }
            const aLogin = CipherViewLikeUtils.getLogin(a);
            const bLogin = CipherViewLikeUtils.getLogin(b);
            if (aLogin.username != null) {
                aName += aLogin.username;
            }
            if (bLogin.username != null) {
                bName += bLogin.username;
            }
            return this.i18nService.collator
                ? this.i18nService.collator.compare(aName, bName)
                : aName.localeCompare(bName);
        };
    }
    softDelete(id, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            let ciphers = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.ciphers$(userId));
            if (ciphers == null) {
                return;
            }
            const setDeletedDate = (cipherId) => {
                if (ciphers[cipherId] == null) {
                    return;
                }
                ciphers[cipherId].deletedDate = new Date().toISOString();
            };
            if (typeof id === "string") {
                setDeletedDate(id);
            }
            else {
                id.forEach(setDeletedDate);
            }
            yield this.clearCache();
            yield this.encryptedCiphersState(userId).update(() => {
                if (ciphers == null) {
                    ciphers = {};
                }
                return ciphers;
            });
        });
    }
    softDeleteWithServer(id_1, userId_1) {
        return cipher_service_awaiter(this, arguments, void 0, function* (id, userId, asAdmin = false) {
            const useSdk = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkCipherCrudEnabled$);
            if (useSdk) {
                yield this.clearCache(userId);
                yield this.cipherSdkService.softDeleteWithServer(id, userId, asAdmin);
                return;
            }
            if (asAdmin) {
                yield this.apiService.putDeleteCipherAdmin(id);
            }
            else {
                yield this.apiService.putDeleteCipher(id);
            }
            yield this.softDelete(id, userId);
        });
    }
    softDeleteManyWithServer(ids_1, userId_1) {
        return cipher_service_awaiter(this, arguments, void 0, function* (ids, userId, asAdmin = false, orgId) {
            const useSdk = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkCipherCrudEnabled$);
            if (useSdk) {
                yield this.clearCache(userId);
                yield this.cipherSdkService.softDeleteManyWithServer(ids, userId, asAdmin, orgId);
                return;
            }
            const request = new CipherBulkDeleteRequest(ids, orgId);
            if (asAdmin) {
                yield this.apiService.putDeleteManyCiphersAdmin(request);
            }
            else {
                yield this.apiService.putDeleteManyCiphers(request);
            }
            yield this.softDelete(ids, userId);
        });
    }
    restore(cipher, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            let ciphers = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.ciphers$(userId));
            if (ciphers == null) {
                return;
            }
            const clearDeletedDate = (c) => {
                const cipherId = c.id;
                if (ciphers[cipherId] == null) {
                    return;
                }
                ciphers[cipherId].deletedDate = null;
                ciphers[cipherId].revisionDate = c.revisionDate;
            };
            if (cipher.constructor.name === Array.name) {
                cipher.forEach(clearDeletedDate);
            }
            else {
                clearDeletedDate(cipher);
            }
            yield this.clearCache();
            yield this.encryptedCiphersState(userId).update(() => {
                if (ciphers == null) {
                    ciphers = {};
                }
                return ciphers;
            });
        });
    }
    restoreWithServer(id_1, userId_1) {
        return cipher_service_awaiter(this, arguments, void 0, function* (id, userId, asAdmin = false) {
            const useSdk = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkCipherCrudEnabled$);
            if (useSdk) {
                yield this.clearCache(userId);
                yield this.cipherSdkService.restoreWithServer(id, userId, asAdmin);
                return;
            }
            let response;
            if (asAdmin) {
                response = yield this.apiService.putRestoreCipherAdmin(id);
            }
            else {
                response = yield this.apiService.putRestoreCipher(id);
            }
            yield this.restore({ id: id, revisionDate: response.revisionDate }, userId);
        });
    }
    /**
     * No longer using an asAdmin Param. Org Vault bulkRestore will assess if an item is unassigned or editable
     * The Org Vault will pass those ids an array as well as the orgId when calling bulkRestore
     */
    restoreManyWithServer(ids, userId, orgId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const useSdk = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkCipherCrudEnabled$);
            if (useSdk) {
                yield this.clearCache(userId);
                yield this.cipherSdkService.restoreManyWithServer(ids, userId, orgId);
                return;
            }
            let response;
            if (orgId) {
                const request = new CipherBulkRestoreRequest(ids, orgId);
                response = yield this.apiService.putRestoreManyCiphersAdmin(request);
            }
            else {
                const request = new CipherBulkRestoreRequest(ids);
                response = yield this.apiService.putRestoreManyCiphers(request);
            }
            const restores = [];
            for (const cipher of response.data) {
                restores.push({ id: cipher.id, revisionDate: cipher.revisionDate });
            }
            yield this.restore(restores, userId);
        });
    }
    getKeyForCipherKeyDecryption(cipher, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            if (cipher.organizationId == null) {
                return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.userKey$(userId));
            }
            else {
                return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService
                    .orgKeys$(userId)
                    .pipe((0,external_rxjs_namespaceObject.map)((orgKeys) => orgKeys[cipher.organizationId])));
            }
        });
    }
    setAddEditCipherInfo(value, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            yield this.addEditCipherInfoState(userId).update(() => value, {
                shouldUpdate: (current) => !(current == null && value == null),
            });
        });
    }
    getRotatedData(originalUserKey, newUserKey, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            if (originalUserKey == null) {
                throw new Error("Original user key is required to rotate ciphers");
            }
            if (newUserKey == null) {
                throw new Error("New user key is required to rotate ciphers");
            }
            let encryptedCiphers = [];
            const ciphers = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.cipherViews$(userId));
            const failedCiphers = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.failedToDecryptCiphers$(userId));
            if (!ciphers) {
                return encryptedCiphers;
            }
            if (failedCiphers.length > 0) {
                throw new Error("Cannot rotate ciphers when decryption failures are present");
            }
            const userCiphers = ciphers.filter((c) => c.organizationId == null);
            if (userCiphers.length === 0) {
                return encryptedCiphers;
            }
            const useSdkEncryption = yield this.configService.getFeatureFlag(feature_flag_enum_FeatureFlag.PM22136_SdkCipherEncryption);
            encryptedCiphers = yield Promise.all(userCiphers.map((cipher) => cipher_service_awaiter(this, void 0, void 0, function* () {
                const encryptedCipher = useSdkEncryption
                    ? yield this.cipherEncryptionService.encryptCipherForRotation(cipher, userId, newUserKey)
                    : yield this.encrypt(cipher, userId, newUserKey, originalUserKey);
                return new CipherWithIdRequest(encryptedCipher);
            })));
            return encryptedCiphers;
        });
    }
    /** @inheritdoc */
    getDecryptedAttachmentBuffer(cipherId, attachment, response, userId, useLegacyDecryption) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const useSdkDecryption = yield this.configService.getFeatureFlag(feature_flag_enum_FeatureFlag.PM19941MigrateCipherDomainToSdk);
            const cipherDomain = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.ciphers$(userId).pipe((0,external_rxjs_namespaceObject.map)((ciphersData) => new Cipher(ciphersData[cipherId]))));
            if (useSdkDecryption && !useLegacyDecryption) {
                const encryptedContent = yield response.arrayBuffer();
                return this.cipherEncryptionService.decryptAttachmentContent(cipherDomain, attachment, new Uint8Array(encryptedContent), userId);
            }
            const encBuf = yield EncArrayBuffer.fromResponse(response);
            const key = attachment.key != null
                ? attachment.key
                : cipherDomain.organizationId
                    ? yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.orgKeys$(userId).pipe(filterOutNullish(), (0,external_rxjs_namespaceObject.map)((orgKeys) => orgKeys[cipherDomain.organizationId])))
                    : yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.userKey$(userId).pipe(filterOutNullish()));
            return yield this.encryptService.decryptFileData(encBuf, key);
        });
    }
    /**
     * @returns a SingleUserState
     */
    localDataState(userId) {
        return this.stateProvider.getUser(userId, LOCAL_DATA_KEY);
    }
    /**
     * @returns a SingleUserState for the encrypted ciphers
     */
    encryptedCiphersState(userId) {
        return this.stateProvider.getUser(userId, ENCRYPTED_CIPHERS);
    }
    /**
     * @returns a SingleUserState for the decrypted ciphers
     */
    decryptedCiphersState(userId) {
        return this.stateProvider.getUser(userId, DECRYPTED_CIPHERS);
    }
    /**
     * @returns a SingleUserState for the add/edit cipher info
     */
    addEditCipherInfoState(userId) {
        return this.stateProvider.getUser(userId, ADD_EDIT_CIPHER_INFO_KEY);
    }
    /**
     * @returns a SingleUserState for the failed to decrypt ciphers
     */
    failedToDecryptCiphersState(userId) {
        return this.stateProvider.getUser(userId, FAILED_DECRYPTED_CIPHERS);
    }
    // Helpers
    // In the case of a cipher that is being shared with an organization, we want to decrypt the
    // cipher key with the user's key and then re-encrypt it with the organization's key.
    encryptSharedCipher(model, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const keyForCipherKeyDecryption = yield this.keyService.getUserKey(userId);
            return yield this.encrypt(model, userId, null, keyForCipherKeyDecryption);
        });
    }
    updateModelfromExistingCipher(model, originalCipher, userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const existingCipher = yield this.decrypt(originalCipher, userId);
            model.passwordHistory = existingCipher.passwordHistory || [];
            if (model.type === CipherType.Login && existingCipher.type === CipherType.Login) {
                if (existingCipher.login.password != null &&
                    existingCipher.login.password !== "" &&
                    existingCipher.login.password !== model.login.password) {
                    const ph = new PasswordHistoryView();
                    ph.password = existingCipher.login.password;
                    ph.lastUsedDate = model.login.passwordRevisionDate = new Date();
                    model.passwordHistory.splice(0, 0, ph);
                }
                else {
                    model.login.passwordRevisionDate = existingCipher.login.passwordRevisionDate;
                }
            }
            if (existingCipher.hasFields) {
                const existingHiddenFields = existingCipher.fields.filter((f) => f.type === FieldType.Hidden &&
                    f.name != null &&
                    f.name !== "" &&
                    f.value != null &&
                    f.value !== "");
                const hiddenFields = model.fields == null
                    ? []
                    : model.fields.filter((f) => f.type === FieldType.Hidden && f.name != null && f.name !== "");
                existingHiddenFields.forEach((ef) => {
                    const matchedField = hiddenFields.find((f) => f.name === ef.name);
                    if (matchedField == null || matchedField.value !== ef.value) {
                        const ph = new PasswordHistoryView();
                        ph.password = ef.name + ": " + ef.value;
                        ph.lastUsedDate = new Date();
                        model.passwordHistory.splice(0, 0, ph);
                    }
                });
            }
        });
    }
    adjustPasswordHistoryLength(model) {
        if (model.passwordHistory != null && model.passwordHistory.length === 0) {
            model.passwordHistory = null;
        }
        else if (model.passwordHistory != null && model.passwordHistory.length > 5) {
            // only save last 5 history
            model.passwordHistory = model.passwordHistory.slice(0, 5);
        }
    }
    shareAttachmentWithServer(attachmentView, cipherId, organizationId, lastKnownRevisionDate) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$);
            const attachmentResponse = yield this.apiService.nativeFetch(new Request(attachmentView.url, { cache: "no-store" }));
            if (attachmentResponse.status !== 200) {
                throw Error("Failed to download attachment: " + attachmentResponse.status.toString());
            }
            const encBuf = yield EncArrayBuffer.fromResponse(attachmentResponse);
            const userKey = yield this.keyService.getUserKey(activeUserId.id);
            const decBuf = yield this.encryptService.decryptFileData(encBuf, userKey);
            let encKey;
            encKey = yield this.keyService.getOrgKey(organizationId);
            encKey || (encKey = (yield this.keyService.getUserKey()));
            const dataEncKey = yield this.keyService.makeDataEncKey(encKey);
            const encFileName = yield this.encryptService.encryptString(attachmentView.fileName, encKey);
            const encData = yield this.encryptService.encryptFileData(new Uint8Array(decBuf), dataEncKey[0]);
            const fd = new FormData();
            try {
                const blob = new Blob([encData.buffer], { type: "application/octet-stream" });
                fd.append("key", dataEncKey[1].encryptedString);
                fd.append("data", blob, encFileName.encryptedString);
                fd.append("lastKnownRevisionDate", lastKnownRevisionDate.toISOString());
            }
            catch (e) {
                if (utils_Utils.isNode && !utils_Utils.isBrowser) {
                    fd.append("key", dataEncKey[1].encryptedString);
                    fd.append("lastKnownRevisionDate", lastKnownRevisionDate.toISOString());
                    fd.append("data", Buffer.from(encData.buffer), { filepath: encFileName.encryptedString, contentType: "application/octet-stream" });
                }
                else {
                    throw e;
                }
            }
            try {
                yield this.apiService.postShareCipherAttachment(cipherId, attachmentView.id, fd, organizationId);
            }
            catch (e) {
                throw new Error(e.getSingleMessage());
            }
        });
    }
    /**
     * Upgrade all old attachments for a cipher by downloading, decrypting, re-uploading with new key, and deleting old.
     * @param cipher
     * @param userId
     * @param attachmentId Optional specific attachment ID to upgrade. If not provided, all old attachments will be upgraded.
     */
    upgradeOldCipherAttachments(cipher, userId, attachmentId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            if (!cipher.hasOldAttachments) {
                return cipher;
            }
            let cipherDomain = yield this.get(cipher.id, userId);
            for (const attachmentView of cipher.attachments) {
                if (attachmentView.key != null ||
                    (attachmentId != null && attachmentView.id !== attachmentId)) {
                    continue;
                }
                try {
                    // 1. Get download URL
                    const downloadUrl = yield this.getAttachmentDownloadUrl(cipher.id, attachmentView);
                    // 2. Download attachment data
                    const dataResponse = yield this.apiService.nativeFetch(new Request(downloadUrl, { cache: "no-store" }));
                    if (dataResponse.status !== 200) {
                        throw new Error(`Failed to download attachment. Status: ${dataResponse.status}`);
                    }
                    // 3. Decrypt the attachment
                    const decryptedBuffer = yield this.getDecryptedAttachmentBuffer(cipher.id, attachmentView, dataResponse, userId);
                    // 4. Re-upload with attachment key
                    cipherDomain = yield this.saveAttachmentRawWithServer(cipherDomain, attachmentView.fileName, decryptedBuffer, userId);
                    // 5. Delete the old attachment
                    const cipherData = yield this.deleteAttachmentWithServer(cipher.id, attachmentView.id, userId);
                    cipherDomain = new Cipher(cipherData);
                }
                catch (e) {
                    this.logService.error(`Failed to upgrade attachment ${attachmentView.id}`, e);
                    throw e;
                }
            }
            return yield this.decrypt(cipherDomain, userId);
        });
    }
    getAttachmentDownloadUrl(cipherId, attachmentView) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            try {
                const attachmentResponse = yield this.apiService.getAttachmentData(cipherId, attachmentView.id);
                return attachmentResponse.url;
            }
            catch (e) {
                // Fall back to the attachment's stored URL
                if (e instanceof ErrorResponse && e.statusCode === 404 && attachmentView.url) {
                    return attachmentView.url;
                }
                throw new Error(`Failed to get download URL for attachment ${attachmentView.id}`);
            }
        });
    }
    encryptObjProperty(model, obj, map, key) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const promises = [];
            const self = this;
            for (const prop in map) {
                // eslint-disable-next-line
                if (!map.hasOwnProperty(prop)) {
                    continue;
                }
                (function (theProp, theObj) {
                    const p = Promise.resolve()
                        .then(() => {
                        const modelProp = model[map[theProp] || theProp];
                        if (modelProp && modelProp !== "") {
                            return self.encryptService.encryptString(modelProp, key);
                        }
                        return null;
                    })
                        .then((val) => {
                        theObj[theProp] = val;
                    });
                    promises.push(p);
                })(prop, obj);
            }
            yield Promise.all(promises);
        });
    }
    encryptCipherData(cipher, model, key) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            switch (cipher.type) {
                case CipherType.Login:
                    cipher.login = new Login();
                    cipher.login.passwordRevisionDate = model.login.passwordRevisionDate;
                    cipher.login.autofillOnPageLoad = model.login.autofillOnPageLoad;
                    yield this.encryptObjProperty(model.login, cipher.login, { username: null, password: null, totp: null }, key);
                    if (model.login.uris != null) {
                        cipher.login.uris = [];
                        model.login.uris = model.login.uris.filter((u) => u.uri != null && u.uri !== "");
                        for (let i = 0; i < model.login.uris.length; i++) {
                            const loginUri = new LoginUri();
                            loginUri.match = model.login.uris[i].match;
                            yield this.encryptObjProperty(model.login.uris[i], loginUri, { uri: null }, key);
                            const uriHash = yield this.encryptService.hash(model.login.uris[i].uri, "sha256");
                            loginUri.uriChecksum = yield this.encryptService.encryptString(uriHash, key);
                            cipher.login.uris.push(loginUri);
                        }
                    }
                    if (model.login.fido2Credentials != null) {
                        cipher.login.fido2Credentials = yield Promise.all(model.login.fido2Credentials.map((viewKey) => cipher_service_awaiter(this, void 0, void 0, function* () {
                            const domainKey = new Fido2Credential();
                            yield this.encryptObjProperty(viewKey, domainKey, {
                                credentialId: null,
                                keyType: null,
                                keyAlgorithm: null,
                                keyCurve: null,
                                keyValue: null,
                                rpId: null,
                                rpName: null,
                                userHandle: null,
                                userName: null,
                                userDisplayName: null,
                                origin: null,
                            }, key);
                            domainKey.counter = yield this.encryptService.encryptString(String(viewKey.counter), key);
                            domainKey.discoverable = yield this.encryptService.encryptString(String(viewKey.discoverable), key);
                            domainKey.creationDate = viewKey.creationDate;
                            return domainKey;
                        })));
                    }
                    return;
                case CipherType.SecureNote:
                    cipher.secureNote = new SecureNote();
                    cipher.secureNote.type = model.secureNote.type;
                    return;
                case CipherType.Card:
                    cipher.card = new Card();
                    yield this.encryptObjProperty(model.card, cipher.card, {
                        cardholderName: null,
                        brand: null,
                        number: null,
                        expMonth: null,
                        expYear: null,
                        code: null,
                    }, key);
                    return;
                case CipherType.Identity:
                    cipher.identity = new Identity();
                    yield this.encryptObjProperty(model.identity, cipher.identity, {
                        title: null,
                        firstName: null,
                        middleName: null,
                        lastName: null,
                        address1: null,
                        address2: null,
                        address3: null,
                        city: null,
                        state: null,
                        postalCode: null,
                        country: null,
                        company: null,
                        email: null,
                        phone: null,
                        ssn: null,
                        username: null,
                        passportNumber: null,
                        licenseNumber: null,
                    }, key);
                    return;
                case CipherType.SshKey:
                    cipher.sshKey = new SshKey();
                    yield this.encryptObjProperty(model.sshKey, cipher.sshKey, { privateKey: null, publicKey: null, keyFingerprint: null }, key);
                    return;
                default:
                    throw new Error("Unknown cipher type.");
            }
        });
    }
    getAutofillOnPageLoadDefault() {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.autofillSettingsService.autofillOnPageLoadDefault$);
        });
    }
    getCipherForUrl(url, userId, lastUsed, lastLaunched, autofillOnPageLoad) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const cacheKey = autofillOnPageLoad ? "autofillOnPageLoad-" + url : url;
            if (!this.sortedCiphersCache.isCached(cacheKey)) {
                let ciphers = yield this.getAllDecryptedForUrl(url, userId);
                if (!(ciphers === null || ciphers === void 0 ? void 0 : ciphers.length)) {
                    return null;
                }
                const localData = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.localData$(userId));
                if (localData) {
                    for (const view of ciphers) {
                        const data = localData[view.id];
                        if (data) {
                            view.localData = data;
                        }
                    }
                }
                if (autofillOnPageLoad) {
                    const autofillOnPageLoadDefault = yield this.getAutofillOnPageLoadDefault();
                    ciphers = ciphers.filter((cipher) => cipher.login.autofillOnPageLoad ||
                        (cipher.login.autofillOnPageLoad == null && autofillOnPageLoadDefault !== false));
                    if (ciphers.length === 0) {
                        return null;
                    }
                }
                this.sortedCiphersCache.addCiphers(cacheKey, ciphers);
            }
            if (lastLaunched) {
                return this.sortedCiphersCache.getLastLaunched(cacheKey);
            }
            else if (lastUsed) {
                return this.sortedCiphersCache.getLastUsed(cacheKey);
            }
            else {
                return this.sortedCiphersCache.getNext(cacheKey);
            }
        });
    }
    clearEncryptedCiphersState(userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            // Use null (not {}) so that cipherListViews$/cipherViews$ filter it out
            // and don't emit an empty array during sync.
            yield this.stateProvider.setUserState(ENCRYPTED_CIPHERS, null, userId);
        });
    }
    clearDecryptedCiphersState(userId) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            yield this.setDecryptedCiphers(null, userId);
            yield this.setFailedDecryptedCiphers(null, userId);
            this.clearSortedCiphers();
        });
    }
    clearSortedCiphers() {
        this.sortedCiphersCache.clear();
    }
    /**
     * Encrypts a cipher object.
     * @param model The cipher view model.
     * @param cipher The cipher object.
     * @param key The encryption key to encrypt with. This can be the org key, user key or cipher key, but must never be null
     */
    encryptCipher(model, cipher, key) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            if (key == null) {
                throw new Error("Key to encrypt cipher must not be null. Use the org key, user key or cipher key.");
            }
            yield Promise.all([
                this.encryptObjProperty(model, cipher, { name: null, notes: null }, key),
                this.encryptCipherData(cipher, model, key),
                this.encryptFields(model.fields, key).then((fields) => {
                    cipher.fields = fields;
                }),
                this.encryptPasswordHistories(model.passwordHistory, key).then((ph) => {
                    cipher.passwordHistory = ph;
                }),
                this.encryptAttachments(model.attachments, key).then((attachments) => {
                    cipher.attachments = attachments;
                }),
            ]);
            return cipher;
        });
    }
    encryptCipherWithCipherKey(model, cipher, keyForCipherKeyEncryption, keyForCipherKeyDecryption) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            // First, we get the key for cipher key encryption, in its decrypted form
            let decryptedCipherKey;
            if (cipher.key == null) {
                decryptedCipherKey = yield this.keyService.makeCipherKey();
            }
            else {
                decryptedCipherKey = yield this.encryptService.unwrapSymmetricKey(cipher.key, keyForCipherKeyDecryption);
            }
            // Then, we have to encrypt the cipher key with the proper key.
            cipher.key = yield this.encryptService.wrapSymmetricKey(decryptedCipherKey, keyForCipherKeyEncryption);
            // Finally, we can encrypt the cipher with the decrypted cipher key.
            return this.encryptCipher(model, cipher, decryptedCipherKey);
        });
    }
    getCipherKeyEncryptionEnabled() {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            const featureEnabled = yield this.configService.getFeatureFlag(feature_flag_enum_FeatureFlag.CipherKeyEncryption);
            const meetsServerVersion = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.configService.checkServerMeetsVersionRequirement$(CIPHER_KEY_ENC_MIN_SERVER_VER));
            return featureEnabled && meetsServerVersion;
        });
    }
    decryptCiphersWithSdk(ciphers_1, userId_1) {
        return cipher_service_awaiter(this, arguments, void 0, function* (ciphers, userId, fullDecryption = true) {
            // Short-circuit if there are no ciphers to decrypt
            // Observables reacting to key changes may attempt to decrypt with a stale SDK reference.
            if (ciphers.length === 0) {
                return [[], []];
            }
            if (fullDecryption) {
                const [decryptedViews, failedViews] = yield this.cipherEncryptionService.decryptManyLegacy(ciphers, userId);
                return [decryptedViews.sort(this.getLocaleSortingFunction()), failedViews];
            }
            const [decrypted, failures] = yield this.cipherEncryptionService.decryptManyWithFailures(ciphers, userId);
            const failedViews = failures.map((c) => {
                const cipher_view = new CipherView(c);
                cipher_view.name = "[error: cannot decrypt]";
                cipher_view.decryptionFailure = true;
                return cipher_view;
            });
            return [decrypted.sort(this.getLocaleSortingFunction()), failedViews];
        });
    }
    /** Fetches the full `CipherView` when a `CipherListView` is passed. */
    getFullCipherView(c) {
        return cipher_service_awaiter(this, void 0, void 0, function* () {
            if (CipherViewLikeUtils.isCipherListView(c)) {
                const activeUserId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.map)((a) => a === null || a === void 0 ? void 0 : a.id)));
                const cipher = yield this.get(uuidAsString(c.id), activeUserId);
                return this.decrypt(cipher, activeUserId);
            }
            return Promise.resolve(c);
        });
    }
}

;// ../../libs/common/src/vault/models/request/cipher-bulk-archive.request.ts
class CipherBulkArchiveRequest {
    constructor(ids) {
        this.ids = ids == null ? [] : ids;
    }
}
class CipherBulkUnarchiveRequest {
    constructor(ids) {
        this.ids = ids == null ? [] : ids;
    }
}

;// ../../libs/common/src/vault/services/default-cipher-archive.service.ts
var default_cipher_archive_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};






class DefaultCipherArchiveService {
    constructor(cipherService, apiService, billingAccountProfileStateService) {
        this.cipherService = cipherService;
        this.apiService = apiService;
        this.billingAccountProfileStateService = billingAccountProfileStateService;
    }
    /**
     * Observable that contains the list of ciphers that have been archived.
     */
    archivedCiphers$(userId) {
        return this.cipherService.cipherListViews$(userId).pipe((0,external_rxjs_namespaceObject.filter)((cipher) => cipher != null), (0,external_rxjs_namespaceObject.map)((ciphers) => ciphers.filter((cipher) => CipherViewLikeUtils.isArchived(cipher) && !CipherViewLikeUtils.isDeleted(cipher))));
    }
    /**
     * User can archive items if:
     * User has premium from any source (personal or organization)
     */
    userCanArchive$(userId) {
        return this.billingAccountProfileStateService
            .hasPremiumFromAnySource$(userId)
            .pipe((0,external_rxjs_namespaceObject.shareReplay)({ refCount: true, bufferSize: 1 }));
    }
    /** Returns true when the user has premium from any means. */
    userHasPremium$(userId) {
        return this.billingAccountProfileStateService
            .hasPremiumFromAnySource$(userId)
            .pipe((0,external_rxjs_namespaceObject.shareReplay)({ refCount: true, bufferSize: 1 }));
    }
    /** Returns true when the user has previously archived ciphers but lost their premium membership. */
    showSubscriptionEndedMessaging$(userId) {
        return (0,external_rxjs_namespaceObject.combineLatest)([this.archivedCiphers$(userId), this.userHasPremium$(userId)]).pipe((0,external_rxjs_namespaceObject.map)(([archivedCiphers, hasPremium]) => archivedCiphers.length > 0 && !hasPremium), (0,external_rxjs_namespaceObject.shareReplay)({ refCount: true, bufferSize: 1 }));
    }
    archiveWithServer(ids, userId) {
        return default_cipher_archive_service_awaiter(this, void 0, void 0, function* () {
            const request = new CipherBulkArchiveRequest(Array.isArray(ids) ? ids : [ids]);
            const r = yield this.apiService.send("PUT", "/ciphers/archive", request, true, true);
            const response = new ListResponse(r, cipher_response_CipherResponse);
            const currentCiphers = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.cipherService.ciphers$(userId));
            const responseDataArray = response.data.map((cipher) => { var _a; return new CipherData(cipher, (_a = currentCiphers[cipher.id]) === null || _a === void 0 ? void 0 : _a.collectionIds); });
            yield this.cipherService.upsert(responseDataArray, userId);
            return response.data[0];
        });
    }
    unarchiveWithServer(ids, userId) {
        return default_cipher_archive_service_awaiter(this, void 0, void 0, function* () {
            const request = new CipherBulkUnarchiveRequest(Array.isArray(ids) ? ids : [ids]);
            const r = yield this.apiService.send("PUT", "/ciphers/unarchive", request, true, true);
            const response = new ListResponse(r, cipher_response_CipherResponse);
            const currentCiphers = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.cipherService.ciphers$(userId));
            const responseDataArray = response.data.map((cipher) => { var _a; return new CipherData(cipher, (_a = currentCiphers[cipher.id]) === null || _a === void 0 ? void 0 : _a.collectionIds); });
            yield this.cipherService.upsert(responseDataArray, userId);
            return response.data[0];
        });
    }
}

;// ../../libs/common/src/vault/services/default-cipher-encryption.service.ts
var default_cipher_encryption_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var default_cipher_encryption_service_addDisposableResource = (undefined && undefined.__addDisposableResource) || function (env, value, async) {
    if (value !== null && value !== void 0) {
        if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
        var dispose, inner;
        if (async) {
            if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
            dispose = value[Symbol.asyncDispose];
        }
        if (dispose === void 0) {
            if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
            dispose = value[Symbol.dispose];
            if (async) inner = dispose;
        }
        if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
        if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
        env.stack.push({ value: value, dispose: dispose, async: async });
    }
    else if (async) {
        env.stack.push({ async: true });
    }
    return value;
};
var default_cipher_encryption_service_disposeResources = (undefined && undefined.__disposeResources) || (function (SuppressedError) {
    return function (env) {
        function fail(e) {
            env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
            env.hasError = true;
        }
        var r, s = 0;
        function next() {
            while (r = env.stack.pop()) {
                try {
                    if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
                    if (r.dispose) {
                        var result = r.dispose.call(r.value);
                        if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
                    }
                    else s |= 1;
                }
                catch (e) {
                    fail(e);
                }
            }
            if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
            if (env.hasError) throw env.error;
        }
        return next();
    };
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
    var e = new Error(message);
    return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
});






class DefaultCipherEncryptionService {
    constructor(sdkService, logService) {
        this.sdkService = sdkService;
        this.logService = logService;
    }
    encrypt(model, userId) {
        return default_cipher_encryption_service_awaiter(this, void 0, void 0, function* () {
            return (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkService.userClient$(userId).pipe((0,external_rxjs_namespaceObject.concatMap)((sdk) => default_cipher_encryption_service_awaiter(this, void 0, void 0, function* () {
                const env_1 = { stack: [], error: void 0, hasError: false };
                try {
                    if (!sdk) {
                        throw new Error("SDK not available");
                    }
                    const ref = default_cipher_encryption_service_addDisposableResource(env_1, sdk.take(), false);
                    const sdkCipherView = model.toSdkCipherView(ref.value.vault().ciphers());
                    const encryptionContext = yield ref.value.vault().ciphers().encrypt(sdkCipherView);
                    return {
                        cipher: Cipher.fromSdkCipher(encryptionContext.cipher),
                        encryptedFor: uuidAsString(encryptionContext.encryptedFor),
                    };
                }
                catch (e_1) {
                    env_1.error = e_1;
                    env_1.hasError = true;
                }
                finally {
                    default_cipher_encryption_service_disposeResources(env_1);
                }
            })), (0,external_rxjs_namespaceObject.catchError)((error) => {
                this.logService.error(`Failed to encrypt cipher: ${error}`);
                return external_rxjs_namespaceObject.EMPTY;
            })));
        });
    }
    encryptMany(models, userId) {
        return default_cipher_encryption_service_awaiter(this, void 0, void 0, function* () {
            if (!models || models.length === 0) {
                return [];
            }
            return (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkService.userClient$(userId).pipe((0,external_rxjs_namespaceObject.concatMap)((sdk) => default_cipher_encryption_service_awaiter(this, void 0, void 0, function* () {
                const env_2 = { stack: [], error: void 0, hasError: false };
                try {
                    if (!sdk) {
                        throw new Error("SDK not available");
                    }
                    const ref = default_cipher_encryption_service_addDisposableResource(env_2, sdk.take(), false);
                    const results = yield ref.value
                        .vault()
                        .ciphers()
                        .encrypt_list(models.map((model) => model.toSdkCipherView(ref.value.vault().ciphers())));
                    return results.map((encryptionContext) => ({
                        cipher: Cipher.fromSdkCipher(encryptionContext.cipher),
                        encryptedFor: uuidAsString(encryptionContext.encryptedFor),
                    }));
                }
                catch (e_2) {
                    env_2.error = e_2;
                    env_2.hasError = true;
                }
                finally {
                    default_cipher_encryption_service_disposeResources(env_2);
                }
            })), (0,external_rxjs_namespaceObject.catchError)((error) => {
                this.logService.error(`Failed to encrypt ciphers in batch: ${error}`);
                return external_rxjs_namespaceObject.EMPTY;
            })));
        });
    }
    moveToOrganization(model, organizationId, userId) {
        return default_cipher_encryption_service_awaiter(this, void 0, void 0, function* () {
            return (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkService.userClient$(userId).pipe((0,external_rxjs_namespaceObject.concatMap)((sdk) => default_cipher_encryption_service_awaiter(this, void 0, void 0, function* () {
                const env_3 = { stack: [], error: void 0, hasError: false };
                try {
                    if (!sdk) {
                        throw new Error("SDK not available");
                    }
                    const ref = default_cipher_encryption_service_addDisposableResource(env_3, sdk.take(), false);
                    const sdkCipherView = model.toSdkCipherView(ref.value.vault().ciphers());
                    const movedCipherView = ref.value
                        .vault()
                        .ciphers()
                        .move_to_organization(sdkCipherView, asUuid(organizationId));
                    const encryptionContext = yield ref.value.vault().ciphers().encrypt(movedCipherView);
                    return {
                        cipher: Cipher.fromSdkCipher(encryptionContext.cipher),
                        encryptedFor: uuidAsString(encryptionContext.encryptedFor),
                    };
                }
                catch (e_3) {
                    env_3.error = e_3;
                    env_3.hasError = true;
                }
                finally {
                    default_cipher_encryption_service_disposeResources(env_3);
                }
            })), (0,external_rxjs_namespaceObject.catchError)((error) => {
                this.logService.error(`Failed to move cipher to organization: ${error}`);
                return external_rxjs_namespaceObject.EMPTY;
            })));
        });
    }
    encryptCipherForRotation(model, userId, newKey) {
        return default_cipher_encryption_service_awaiter(this, void 0, void 0, function* () {
            return (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkService.userClient$(userId).pipe((0,external_rxjs_namespaceObject.concatMap)((sdk) => default_cipher_encryption_service_awaiter(this, void 0, void 0, function* () {
                const env_4 = { stack: [], error: void 0, hasError: false };
                try {
                    if (!sdk) {
                        throw new Error("SDK not available");
                    }
                    const ref = default_cipher_encryption_service_addDisposableResource(env_4, sdk.take(), false);
                    const sdkCipherView = model.toSdkCipherView(ref.value.vault().ciphers());
                    const encryptionContext = yield ref.value
                        .vault()
                        .ciphers()
                        .encrypt_cipher_for_rotation(sdkCipherView, newKey.toBase64());
                    return {
                        cipher: Cipher.fromSdkCipher(encryptionContext.cipher),
                        encryptedFor: uuidAsString(encryptionContext.encryptedFor),
                    };
                }
                catch (e_4) {
                    env_4.error = e_4;
                    env_4.hasError = true;
                }
                finally {
                    default_cipher_encryption_service_disposeResources(env_4);
                }
            })), (0,external_rxjs_namespaceObject.catchError)((error) => {
                this.logService.error(`Failed to rotate cipher data: ${error}`);
                return external_rxjs_namespaceObject.EMPTY;
            })));
        });
    }
    decrypt(cipher, userId) {
        return default_cipher_encryption_service_awaiter(this, void 0, void 0, function* () {
            return (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkService.userClient$(userId).pipe((0,external_rxjs_namespaceObject.concatMap)((sdk) => default_cipher_encryption_service_awaiter(this, void 0, void 0, function* () {
                var _a, _b;
                const env_5 = { stack: [], error: void 0, hasError: false };
                try {
                    if (!sdk) {
                        throw new Error("SDK not available");
                    }
                    const ref = default_cipher_encryption_service_addDisposableResource(env_5, sdk.take(), false);
                    const sdkCipherView = yield ref.value.vault().ciphers().decrypt(cipher.toSdkCipher());
                    const clientCipherView = CipherView.fromSdkCipherView(sdkCipherView);
                    // Decrypt Fido2 credentials if available
                    if (clientCipherView.type === CipherType.Login &&
                        ((_b = (_a = sdkCipherView.login) === null || _a === void 0 ? void 0 : _a.fido2Credentials) === null || _b === void 0 ? void 0 : _b.length)) {
                        const fido2CredentialViews = ref.value
                            .vault()
                            .ciphers()
                            .decrypt_fido2_credentials(sdkCipherView);
                        // TEMPORARY: Manually decrypt the keyValue for Fido2 credentials
                        // since we don't currently use the SDK for Fido2 Authentication.
                        const decryptedKeyValue = ref.value
                            .vault()
                            .ciphers()
                            .decrypt_fido2_private_key(sdkCipherView);
                        clientCipherView.login.fido2Credentials = fido2CredentialViews
                            .map((f) => {
                            const view = Fido2CredentialView.fromSdkFido2CredentialView(f);
                            view.keyValue = decryptedKeyValue;
                            return view;
                        })
                            .filter((view) => view !== undefined);
                    }
                    return clientCipherView;
                }
                catch (e_5) {
                    env_5.error = e_5;
                    env_5.hasError = true;
                }
                finally {
                    default_cipher_encryption_service_disposeResources(env_5);
                }
            })), (0,external_rxjs_namespaceObject.catchError)((error) => {
                this.logService.error(`Failed to decrypt cipher ${error}`);
                return external_rxjs_namespaceObject.EMPTY;
            })));
        });
    }
    decryptManyLegacy(ciphers, userId) {
        return (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkService.userClient$(userId).pipe((0,external_rxjs_namespaceObject.concatMap)((sdk) => default_cipher_encryption_service_awaiter(this, void 0, void 0, function* () {
            var _a, _b;
            const env_6 = { stack: [], error: void 0, hasError: false };
            try {
                if (!sdk) {
                    throw new Error("SDK not available");
                }
                const ref = default_cipher_encryption_service_addDisposableResource(env_6, sdk.take(), false);
                const successful = [];
                const failed = [];
                for (const cipher of ciphers) {
                    try {
                        const sdkCipherView = yield ref.value.vault().ciphers().decrypt(cipher.toSdkCipher());
                        const clientCipherView = CipherView.fromSdkCipherView(sdkCipherView);
                        // Handle FIDO2 credentials if present
                        if (clientCipherView.type === CipherType.Login &&
                            ((_b = (_a = sdkCipherView.login) === null || _a === void 0 ? void 0 : _a.fido2Credentials) === null || _b === void 0 ? void 0 : _b.length)) {
                            const fido2CredentialViews = ref.value
                                .vault()
                                .ciphers()
                                .decrypt_fido2_credentials(sdkCipherView);
                            const decryptedKeyValue = ref.value
                                .vault()
                                .ciphers()
                                .decrypt_fido2_private_key(sdkCipherView);
                            clientCipherView.login.fido2Credentials = fido2CredentialViews
                                .map((f) => {
                                const view = Fido2CredentialView.fromSdkFido2CredentialView(f);
                                view.keyValue = decryptedKeyValue;
                                return view;
                            })
                                .filter((view) => view !== undefined);
                        }
                        successful.push(clientCipherView);
                    }
                    catch (error) {
                        this.logService.error(`Failed to decrypt cipher ${cipher.id}: ${error}`);
                        const failedView = new CipherView(cipher);
                        failedView.name = "[error: cannot decrypt]";
                        failedView.decryptionFailure = true;
                        failed.push(failedView);
                    }
                }
                return [successful, failed];
            }
            catch (e_6) {
                env_6.error = e_6;
                env_6.hasError = true;
            }
            finally {
                default_cipher_encryption_service_disposeResources(env_6);
            }
        })), (0,external_rxjs_namespaceObject.catchError)((error) => {
            this.logService.error(`Failed to decrypt ciphers: ${error}`);
            return external_rxjs_namespaceObject.EMPTY;
        })));
    }
    decryptManyWithFailures(ciphers, userId) {
        return default_cipher_encryption_service_awaiter(this, void 0, void 0, function* () {
            return (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkService.userClient$(userId).pipe((0,external_rxjs_namespaceObject.concatMap)((sdk) => default_cipher_encryption_service_awaiter(this, void 0, void 0, function* () {
                const env_7 = { stack: [], error: void 0, hasError: false };
                try {
                    if (!sdk) {
                        throw new Error("SDK is undefined");
                    }
                    const ref = default_cipher_encryption_service_addDisposableResource(env_7, sdk.take(), false);
                    const result = yield ref.value
                        .vault()
                        .ciphers()
                        .decrypt_list_with_failures(ciphers.map((cipher) => cipher.toSdkCipher()));
                    const decryptedCiphers = result.successes;
                    const failedCiphers = result.failures
                        .map((cipher) => Cipher.fromSdkCipher(cipher))
                        .filter((cipher) => cipher !== undefined);
                    return [decryptedCiphers, failedCiphers];
                }
                catch (e_7) {
                    env_7.error = e_7;
                    env_7.hasError = true;
                }
                finally {
                    default_cipher_encryption_service_disposeResources(env_7);
                }
            }))));
        });
    }
    /**
     * Decrypts an attachment's content from a response object.
     *
     * @param cipher The encrypted cipher object that owns the attachment
     * @param attachment The encrypted attachment object
     * @param encryptedContent The encrypted content as a Uint8Array
     * @param userId The user ID whose key will be used for decryption
     *
     * @returns A promise that resolves to the decrypted content
     */
    decryptAttachmentContent(cipher, attachment, encryptedContent, userId) {
        return default_cipher_encryption_service_awaiter(this, void 0, void 0, function* () {
            return (0,external_rxjs_namespaceObject.firstValueFrom)(this.sdkService.userClient$(userId).pipe((0,external_rxjs_namespaceObject.map)((sdk) => {
                const env_8 = { stack: [], error: void 0, hasError: false };
                try {
                    if (!sdk) {
                        throw new Error("SDK is undefined");
                    }
                    const ref = default_cipher_encryption_service_addDisposableResource(env_8, sdk.take(), false);
                    return ref.value
                        .vault()
                        .attachments()
                        .decrypt_buffer(cipher.toSdkCipher(), attachment.toSdkAttachmentView(), encryptedContent);
                }
                catch (e_8) {
                    env_8.error = e_8;
                    env_8.hasError = true;
                }
                finally {
                    default_cipher_encryption_service_disposeResources(env_8);
                }
            }), (0,external_rxjs_namespaceObject.catchError)((error) => {
                this.logService.error(`Failed to decrypt cipher buffer: ${error}`);
                return external_rxjs_namespaceObject.EMPTY;
            })));
        });
    }
}

;// ../../libs/common/src/vault/services/file-upload/cipher-file-upload.service.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
var cipher_file_upload_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};


class CipherFileUploadService {
    constructor(apiService, fileUploadService, configService) {
        this.apiService = apiService;
        this.fileUploadService = fileUploadService;
        this.configService = configService;
    }
    upload(cipher, encFileName, encData, admin, dataEncKey, options) {
        return cipher_file_upload_service_awaiter(this, void 0, void 0, function* () {
            const request = {
                key: dataEncKey[1].encryptedString,
                fileName: encFileName.encryptedString,
                fileSize: encData.buffer.byteLength,
                adminRequest: admin,
                lastKnownRevisionDate: cipher.revisionDate,
            };
            const progressEnabled = yield this.configService.getFeatureFlag(feature_flag_enum_FeatureFlag.PM34410AttachmentUploadProgress);
            const opts = progressEnabled ? options : undefined;
            let response;
            try {
                const uploadDataResponse = yield this.apiService.postCipherAttachment(cipher.id, request);
                response = admin ? uploadDataResponse.cipherMiniResponse : uploadDataResponse.cipherResponse;
                yield this.fileUploadService.upload(uploadDataResponse, encFileName, encData, this.generateMethods(uploadDataResponse, response, request.adminRequest, opts), opts);
            }
            catch (e) {
                if (e instanceof ErrorResponse) {
                    throw new Error(e.getSingleMessage());
                }
                else {
                    throw e;
                }
            }
            return response;
        });
    }
    generateMethods(uploadData, response, isAdmin, options) {
        return {
            postDirect: this.generatePostDirectCallback(uploadData, isAdmin, options),
            renewFileUploadUrl: this.generateRenewFileUploadUrlCallback(uploadData, response, isAdmin),
            rollback: this.generateRollbackCallback(response, uploadData, isAdmin),
        };
    }
    generatePostDirectCallback(uploadData, isAdmin, options) {
        return (data) => {
            const response = isAdmin ? uploadData.cipherMiniResponse : uploadData.cipherResponse;
            return this.apiService.postAttachmentFile(response.id, uploadData.attachmentId, data, options);
        };
    }
    generateRenewFileUploadUrlCallback(uploadData, response, isAdmin) {
        return () => cipher_file_upload_service_awaiter(this, void 0, void 0, function* () {
            const renewResponse = yield this.apiService.renewAttachmentUploadUrl(response.id, uploadData.attachmentId);
            return renewResponse === null || renewResponse === void 0 ? void 0 : renewResponse.url;
        });
    }
    generateRollbackCallback(response, uploadData, isAdmin) {
        return () => cipher_file_upload_service_awaiter(this, void 0, void 0, function* () {
            if (isAdmin) {
                yield this.apiService.deleteCipherAttachmentAdmin(response.id, uploadData.attachmentId);
            }
            else {
                yield this.apiService.deleteCipherAttachment(response.id, uploadData.attachmentId);
            }
        });
    }
}

;// ../../libs/common/src/vault/models/request/folder.request.ts
class FolderRequest {
    constructor(folder) {
        var _a;
        if (((_a = folder.name) === null || _a === void 0 ? void 0 : _a.encryptedString) == null) {
            throw new Error("Folder name is required");
        }
        this.name = folder.name.encryptedString;
    }
}

;// ../../libs/common/src/vault/models/response/folder.response.ts

class folder_response_FolderResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.id = this.getResponseProperty("Id");
        this.name = this.getResponseProperty("Name");
        this.revisionDate = this.getResponseProperty("RevisionDate");
    }
}

;// ../../libs/common/src/vault/services/folder/folder-api.service.ts
var folder_api_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};



class FolderApiService {
    constructor(folderService, apiService) {
        this.folderService = folderService;
        this.apiService = apiService;
    }
    save(folder, userId) {
        return folder_api_service_awaiter(this, void 0, void 0, function* () {
            const request = new FolderRequest(folder);
            let response;
            if (folder.id) {
                response = yield this.putFolder(folder.id, request);
            }
            else {
                response = yield this.postFolder(request);
                folder.id = response.id;
            }
            const data = new FolderData(response);
            yield this.folderService.upsert(data, userId);
            return data;
        });
    }
    delete(id, userId) {
        return folder_api_service_awaiter(this, void 0, void 0, function* () {
            yield this.deleteFolder(id);
            yield this.folderService.delete(id, userId);
        });
    }
    deleteAll(userId) {
        return folder_api_service_awaiter(this, void 0, void 0, function* () {
            yield this.apiService.send("DELETE", "/folders/all", null, true, false);
            yield this.folderService.clear(userId);
        });
    }
    get(id) {
        return folder_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("GET", "/folders/" + id, null, true, true);
            return new folder_response_FolderResponse(r);
        });
    }
    postFolder(request) {
        return folder_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("POST", "/folders", request, true, true);
            return new folder_response_FolderResponse(r);
        });
    }
    putFolder(id, request) {
        return folder_api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.apiService.send("PUT", "/folders/" + id, request, true, true);
            return new folder_response_FolderResponse(r);
        });
    }
    deleteFolder(id) {
        return this.apiService.send("DELETE", "/folders/" + id, null, true, false);
    }
}

;// ../../libs/common/src/vault/models/request/folder-with-id.request.ts

class FolderWithIdRequest extends FolderRequest {
    constructor(folder) {
        super(folder);
        this.id = folder.id;
    }
}

;// ../../libs/common/src/vault/services/key-state/folder.state.ts



const FOLDER_ENCRYPTED_FOLDERS = UserKeyDefinition.record(FOLDER_DISK, "folders", {
    deserializer: (obj) => FolderData.fromJSON(obj),
    clearOn: ["logout"],
});
const FOLDER_DECRYPTED_FOLDERS = new UserKeyDefinition(FOLDER_MEMORY, "decryptedFolders", {
    deserializer: (obj) => { var _a; return (_a = obj === null || obj === void 0 ? void 0 : obj.map((f) => FolderView.fromJSON(f))) !== null && _a !== void 0 ? _a : []; },
    clearOn: ["logout", "lock"],
});

;// ../../libs/common/src/vault/services/folder/folder.service.ts
var folder_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore







class FolderService {
    constructor(keyService, encryptService, i18nService, cipherService, stateProvider) {
        this.keyService = keyService;
        this.encryptService = encryptService;
        this.i18nService = i18nService;
        this.cipherService = cipherService;
        this.stateProvider = stateProvider;
        /**
         * Ensures we reuse the same observable stream for each userId rather than
         * creating a new one on each folderViews$ call.
         */
        this.folderViewCache = new Map();
        /**
         * Used to force the folderviews$ Observable to re-emit with a provided value.
         * Required because shareReplay with refCount: false maintains last emission.
         * Used during cleanup to force emit empty arrays, ensuring stale data isn't retained.
         */
        this.forceFolderViews = {};
    }
    folders$(userId) {
        return this.encryptedFoldersState(userId).state$.pipe((0,external_rxjs_namespaceObject.map)((folders) => {
            if (folders == null) {
                return [];
            }
            return Object.values(folders).map((f) => new Folder(f));
        }));
    }
    /**
     * Returns an Observable of decrypted folder views for the given userId.
     * Uses folderViewCache to maintain a single Observable instance per user,
     * combining normal folder state updates with forced updates.
     */
    folderViews$(userId) {
        if (!this.folderViewCache.has(userId)) {
            if (!this.forceFolderViews[userId]) {
                this.forceFolderViews[userId] = new external_rxjs_namespaceObject.Subject();
            }
            const observable = (0,external_rxjs_namespaceObject.merge)(this.forceFolderViews[userId], (0,external_rxjs_namespaceObject.combineLatest)([
                this.encryptedFoldersState(userId).state$,
                this.keyService.userKey$(userId),
            ]).pipe((0,external_rxjs_namespaceObject.filter)(([folderData, userKey]) => folderData != null && userKey != null), (0,external_rxjs_namespaceObject.switchMap)(([folderData, _]) => {
                return this.decryptFolders(userId, folderData);
            }))).pipe((0,external_rxjs_namespaceObject.shareReplay)({ refCount: false, bufferSize: 1 }));
            this.folderViewCache.set(userId, observable);
        }
        return this.folderViewCache.get(userId);
    }
    // TODO: This should be moved to EncryptService or something
    encrypt(model, key) {
        return folder_service_awaiter(this, void 0, void 0, function* () {
            const folder = new Folder();
            folder.id = model.id;
            folder.name = yield this.encryptService.encryptString(model.name, key);
            return folder;
        });
    }
    get(id, userId) {
        return folder_service_awaiter(this, void 0, void 0, function* () {
            const folders = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.folders$(userId));
            return folders.find((folder) => folder.id === id);
        });
    }
    getDecrypted$(id, userId) {
        return this.folderViews$(userId).pipe((0,external_rxjs_namespaceObject.map)((folders) => folders.find((folder) => folder.id === id)), (0,external_rxjs_namespaceObject.shareReplay)({ refCount: true, bufferSize: 1 }));
    }
    getAllFromState(userId) {
        return folder_service_awaiter(this, void 0, void 0, function* () {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.folders$(userId));
        });
    }
    /**
     * @deprecated For the CLI only
     * @param id id of the folder
     */
    getFromState(id, userId) {
        return folder_service_awaiter(this, void 0, void 0, function* () {
            const folder = yield this.get(id, userId);
            if (!folder) {
                return null;
            }
            return folder;
        });
    }
    /**
     * @deprecated Only use in CLI!
     */
    getAllDecryptedFromState(userId) {
        return folder_service_awaiter(this, void 0, void 0, function* () {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.folderViews$(userId));
        });
    }
    upsert(folderData, userId) {
        return folder_service_awaiter(this, void 0, void 0, function* () {
            yield this.clearDecryptedFolderState(userId);
            yield this.encryptedFoldersState(userId).update((folders) => {
                if (folders == null) {
                    folders = {};
                }
                if (folderData instanceof FolderData) {
                    const f = folderData;
                    folders[f.id] = f;
                }
                else {
                    folderData.forEach((f) => {
                        folders[f.id] = f;
                    });
                }
                return folders;
            });
        });
    }
    replace(folders, userId) {
        return folder_service_awaiter(this, void 0, void 0, function* () {
            if (!folders) {
                return;
            }
            yield this.clearDecryptedFolderState(userId);
            yield this.stateProvider.getUser(userId, FOLDER_ENCRYPTED_FOLDERS).update(() => {
                const newFolders = Object.assign({}, folders);
                return newFolders;
            });
        });
    }
    clearDecryptedFolderState(userId) {
        return folder_service_awaiter(this, void 0, void 0, function* () {
            if (userId == null) {
                throw new Error("User ID is required.");
            }
            yield this.setDecryptedFolders([], userId);
        });
    }
    clear(userId) {
        return folder_service_awaiter(this, void 0, void 0, function* () {
            var _a;
            (_a = this.forceFolderViews[userId]) === null || _a === void 0 ? void 0 : _a.next([]);
            yield this.encryptedFoldersState(userId).update(() => ({}));
            yield this.clearDecryptedFolderState(userId);
        });
    }
    delete(id, userId) {
        return folder_service_awaiter(this, void 0, void 0, function* () {
            yield this.clearDecryptedFolderState(userId);
            yield this.encryptedFoldersState(userId).update((folders) => {
                if (folders == null) {
                    return;
                }
                const folderIdsToDelete = Array.isArray(id) ? id : [id];
                folderIdsToDelete.forEach((id) => {
                    if (folders[id] != null) {
                        delete folders[id];
                    }
                });
                return folders;
            });
            // Items in a deleted folder are re-assigned to "No Folder"
            const ciphers = yield this.cipherService.getAll(userId);
            if (ciphers != null) {
                const updates = [];
                for (const cId in ciphers) {
                    if (ciphers[cId].folderId === id) {
                        ciphers[cId].folderId = null;
                        updates.push(ciphers[cId]);
                    }
                }
                if (updates.length > 0) {
                    yield this.cipherService.upsert(updates.map((c) => c.toCipherData()));
                }
            }
        });
    }
    getRotatedData(originalUserKey, newUserKey, userId) {
        return folder_service_awaiter(this, void 0, void 0, function* () {
            if (newUserKey == null) {
                throw new Error("New user key is required for rotation.");
            }
            let encryptedFolders = [];
            const folders = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.folderViews$(userId));
            if (!folders) {
                return encryptedFolders;
            }
            encryptedFolders = yield Promise.all(folders
                // Filter out "No folder"
                .filter((folder) => !utils_Utils.isNullOrEmpty(folder.id))
                .map((folder) => folder_service_awaiter(this, void 0, void 0, function* () {
                const encryptedFolder = yield this.encrypt(folder, newUserKey);
                return new FolderWithIdRequest(encryptedFolder);
            })));
            return encryptedFolders;
        });
    }
    /**
     * Decrypts the folders for a user.
     * @param userId the user id
     * @param folderData encrypted folders
     * @returns a list of decrypted folders
     */
    decryptFolders(userId, folderData) {
        return folder_service_awaiter(this, void 0, void 0, function* () {
            // Check if the decrypted folders are already cached
            const decrypted = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.stateProvider.getUser(userId, FOLDER_DECRYPTED_FOLDERS).state$);
            if (decrypted === null || decrypted === void 0 ? void 0 : decrypted.length) {
                return decrypted;
            }
            if (folderData == null) {
                return [];
            }
            const folders = Object.values(folderData).map((f) => new Folder(f));
            const userKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.userKey$(userId));
            if (!userKey) {
                return [];
            }
            const decryptFolderPromises = folders.map((f) => folder_service_awaiter(this, void 0, void 0, function* () {
                try {
                    return yield f.decryptWithKey(userKey, this.encryptService);
                }
                catch (_a) {
                    return null;
                }
            }));
            const decryptedFolders = (yield Promise.all(decryptFolderPromises))
                .filter((p) => p !== null)
                .sort(utils_Utils.getSortFunction(this.i18nService, "name"));
            const noneFolder = new FolderView();
            noneFolder.name = this.i18nService.t("noneFolder");
            decryptedFolders.push(noneFolder);
            // Cache the decrypted folders
            yield this.setDecryptedFolders(decryptedFolders, userId);
            return decryptedFolders;
        });
    }
    /**
     * @returns a SingleUserState for the encrypted folders.
     */
    encryptedFoldersState(userId) {
        return this.stateProvider.getUser(userId, FOLDER_ENCRYPTED_FOLDERS);
    }
    /**
     * Sets the decrypted folders state for a user.
     * @param folders the decrypted folders
     * @param userId the user id
     */
    setDecryptedFolders(folders, userId) {
        return folder_service_awaiter(this, void 0, void 0, function* () {
            yield this.stateProvider.setUserState(FOLDER_DECRYPTED_FOLDERS, folders, userId);
        });
    }
}

;// ../../libs/common/src/vault/services/restricted-item-types.service.ts







class RestrictedItemTypesService {
    constructor(accountService, organizationService, policyService) {
        this.accountService = accountService;
        this.organizationService = organizationService;
        this.policyService = policyService;
        /**
         * Emits an array of RestrictedCipherType objects:
         * - cipherType: each type restricted by at least one org-level policy
         * - allowViewOrgIds: org IDs that allow viewing that type
         */
        this.restricted$ = this.accountService.activeAccount$.pipe(getOptionalUserId, (0,operators_namespaceObject.switchMap)((userId) => {
            if (userId == null) {
                return (0,external_rxjs_namespaceObject.of)([]); // No user logged in, no restrictions
            }
            return (0,external_rxjs_namespaceObject.combineLatest)([
                this.organizationService.organizations$(userId),
                this.policyService.policiesByType$(policy_type_enum_PolicyType.RestrictedItemTypes, userId),
            ]).pipe((0,external_rxjs_namespaceObject.map)(([orgs, enabledPolicies]) => {
                // Helper to extract restricted types, defaulting to [Card]
                const restrictedTypes = (p) => { var _a; return (_a = p.data) !== null && _a !== void 0 ? _a : [CipherType.Card]; };
                // Union across all enabled policies
                const allRestrictedTypes = Array.from(new Set(enabledPolicies.flatMap(restrictedTypes)));
                return allRestrictedTypes.map((cipherType) => {
                    // Determine which orgs allow viewing this type
                    const allowViewOrgIds = orgs
                        .filter((org) => {
                        const orgPolicy = enabledPolicies.find((p) => p.organizationId === org.id);
                        // no policy for this org => allows everything
                        if (!orgPolicy) {
                            return true;
                        }
                        // if this type not in their restricted list => they allow it
                        return !restrictedTypes(orgPolicy).includes(cipherType);
                    })
                        .map((org) => org.id);
                    return { cipherType, allowViewOrgIds };
                });
            }));
        }), (0,operators_namespaceObject.distinctUntilChanged)(), (0,operators_namespaceObject.shareReplay)({ bufferSize: 1, refCount: true }));
    }
    /**
     * Determines if a cipher is restricted from being viewed by the user.
     *
     * @param cipher - The cipher to check
     * @param restrictedTypes - Array of restricted cipher types (from restricted$ observable)
     * @returns true if the cipher is restricted, false otherwise
     *
     * Restriction logic:
     * - If cipher type is not restricted by any org → allowed
     * - If cipher belongs to an org that allows this type → allowed
     * - Otherwise → restricted
     */
    isCipherRestricted(cipher, restrictedTypes) {
        const restriction = restrictedTypes.find((r) => r.cipherType === CipherViewLikeUtils.getType(cipher));
        // If cipher type is not restricted by any organization, allow it
        if (!restriction) {
            return false;
        }
        // If cipher belongs to an organization
        if (cipher.organizationId) {
            // Check if this organization allows viewing this cipher type
            return !restriction.allowViewOrgIds.includes(uuidAsString(cipher.organizationId));
        }
        // Cipher is restricted by at least one organization, restrict it
        return true;
    }
    /**
     * Convenience method that combines getting restrictions and checking a cipher.
     *
     * @param cipher - The cipher to check
     * @returns Observable<boolean> indicating if the cipher is restricted
     */
    isCipherRestricted$(cipher) {
        return this.restricted$.pipe((0,external_rxjs_namespaceObject.map)((restrictedTypes) => this.isCipherRestricted(cipher, restrictedTypes)));
    }
}

;// external "lunr"
const external_lunr_namespaceObject = require("lunr");
;// ../../libs/common/src/vault/services/search.service.ts
var search_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore









// Time to wait before performing a search after the user stops typing.
const SearchTextDebounceInterval = 200; // milliseconds
/**
 * The `KeyDefinition` for accessing the search index in application state.
 * The key definition is configured to clear the index when the user locks the vault.
 */
const LUNR_SEARCH_INDEX = new UserKeyDefinition(VAULT_SEARCH_MEMORY, "searchIndex", {
    deserializer: (obj) => obj,
    clearOn: ["lock", "logout"],
});
/**
 * The `KeyDefinition` for accessing the ID of the entity currently indexed by Lunr search.
 * The key definition is configured to clear the indexed entity ID when the user locks the vault.
 */
const LUNR_SEARCH_INDEXED_ENTITY_ID = new UserKeyDefinition(VAULT_SEARCH_MEMORY, "searchIndexedEntityId", {
    deserializer: (obj) => obj,
    clearOn: ["lock", "logout"],
});
/**
 * The `KeyDefinition` for accessing the state of Lunr search indexing, indicating whether the Lunr search index is currently being built or updating.
 * The key definition is configured to clear the indexing state when the user locks the vault.
 */
const LUNR_SEARCH_INDEXING = new UserKeyDefinition(VAULT_SEARCH_MEMORY, "isIndexing", {
    deserializer: (obj) => obj,
    clearOn: ["lock", "logout"],
});
class SearchService {
    constructor(logService, i18nService, stateProvider) {
        this.logService = logService;
        this.i18nService = i18nService;
        this.stateProvider = stateProvider;
        this.immediateSearchLocales = ["zh-CN", "zh-TW", "ja", "ko", "vi"];
        this.defaultSearchableMinLength = 2;
        this.searchableMinLength = this.defaultSearchableMinLength;
        this._isCipherSearching$ = new external_rxjs_namespaceObject.BehaviorSubject(false);
        this.isCipherSearching$ = this._isCipherSearching$.asObservable();
        this._isSendSearching$ = new external_rxjs_namespaceObject.BehaviorSubject(false);
        this.isSendSearching$ = this._isSendSearching$.asObservable();
        this.index$ = perUserCache$((userId) => {
            return this.searchIndexState(userId).state$.pipe((0,external_rxjs_namespaceObject.map)((searchIndex) => {
                let index = null;
                if (searchIndex) {
                    const loadTime = performance.now();
                    index = external_lunr_namespaceObject.Index.load(searchIndex);
                    this.logService.measure(loadTime, "Vault", "SearchService", "index load");
                }
                return index;
            }));
        });
        this.i18nService.locale$.subscribe((locale) => {
            if (this.immediateSearchLocales.indexOf(locale) !== -1) {
                this.searchableMinLength = 1;
            }
            else {
                this.searchableMinLength = this.defaultSearchableMinLength;
            }
        });
        // Currently have to ensure this is only done a single time. Lunr allows you to register a function
        // multiple times but they will add a warning message to the console. The way they do that breaks when ran on a service worker.
        if (!SearchService.registeredPipeline) {
            SearchService.registeredPipeline = true;
            //register lunr pipeline function
            external_lunr_namespaceObject.Pipeline.registerFunction(this.normalizeAccentsPipelineFunction, "normalizeAccents");
        }
    }
    searchIndexState(userId) {
        return this.stateProvider.getUser(userId, LUNR_SEARCH_INDEX);
    }
    searchIndexEntityIdState(userId) {
        return this.stateProvider.getUser(userId, LUNR_SEARCH_INDEXED_ENTITY_ID);
    }
    indexedEntityId$(userId) {
        return this.searchIndexEntityIdState(userId).state$.pipe((0,external_rxjs_namespaceObject.map)((id) => id));
    }
    searchIsIndexingState(userId) {
        return this.stateProvider.getUser(userId, LUNR_SEARCH_INDEXING);
    }
    searchIsIndexing$(userId) {
        return this.searchIsIndexingState(userId).state$.pipe((0,external_rxjs_namespaceObject.map)((indexing) => indexing !== null && indexing !== void 0 ? indexing : false));
    }
    clearIndex(userId) {
        return search_service_awaiter(this, void 0, void 0, function* () {
            yield this.searchIndexEntityIdState(userId).update(() => null);
            yield this.searchIndexState(userId).update(() => null);
            yield this.searchIsIndexingState(userId).update(() => null);
        });
    }
    isSearchable(userId, query) {
        return search_service_awaiter(this, void 0, void 0, function* () {
            query = SearchService.normalizeSearchQuery(query);
            // Nothing to search if the query is null
            if (query == null || query === "") {
                return false;
            }
            const isLunrQuery = query.indexOf(">") === 0;
            if (isLunrQuery) {
                // Lunr queries always require an index
                return (yield this.getIndexForSearch(userId)) != null;
            }
            // Regular queries only require a minimum length
            return query.length >= this.searchableMinLength;
        });
    }
    indexCiphers(userId, ciphers, indexedEntityId) {
        return search_service_awaiter(this, void 0, void 0, function* () {
            if (yield this.getIsIndexing(userId)) {
                return;
            }
            const indexingStartTime = performance.now();
            yield this.setIsIndexing(userId, true);
            yield this.setIndexedEntityIdForSearch(userId, indexedEntityId);
            const builder = new external_lunr_namespaceObject.Builder();
            builder.pipeline.add(this.normalizeAccentsPipelineFunction);
            builder.ref("id");
            builder.field("shortid", {
                boost: 100,
                extractor: (c) => uuidAsString(c.id).substr(0, 8),
            });
            builder.field("name", {
                boost: 10,
            });
            builder.field("subtitle", {
                boost: 5,
                extractor: (c) => {
                    const subtitle = CipherViewLikeUtils.subtitle(c);
                    if (subtitle != null && CipherViewLikeUtils.getType(c) === CipherType.Card) {
                        return subtitle.replace(/\*/g, "");
                    }
                    return subtitle;
                },
            });
            builder.field("notes", { extractor: (c) => CipherViewLikeUtils.getNotes(c) });
            builder.field("login.username", {
                extractor: (c) => {
                    var _a;
                    const login = CipherViewLikeUtils.getLogin(c);
                    return (_a = login === null || login === void 0 ? void 0 : login.username) !== null && _a !== void 0 ? _a : null;
                },
            });
            builder.field("login.uris", {
                boost: 2,
                extractor: (c) => this.uriExtractor(c),
            });
            builder.field("fields", {
                extractor: (c) => this.fieldExtractor(c, false),
            });
            builder.field("fields_joined", {
                extractor: (c) => this.fieldExtractor(c, true),
            });
            builder.field("attachments", {
                extractor: (c) => this.attachmentExtractor(c, false),
            });
            builder.field("attachments_joined", {
                extractor: (c) => this.attachmentExtractor(c, true),
            });
            builder.field("organizationid", { extractor: (c) => c.organizationId });
            ciphers = ciphers || [];
            ciphers.forEach((c) => builder.add(c));
            const index = builder.build();
            yield this.setIndexForSearch(userId, index.toJSON());
            yield this.setIsIndexing(userId, false);
            this.logService.measure(indexingStartTime, "Vault", "SearchService", "index complete", [
                ["Items", ciphers.length],
            ]);
        });
    }
    searchCiphers(userId_1, query_1) {
        return search_service_awaiter(this, arguments, void 0, function* (userId, query, filter = null, ciphers) {
            this._isCipherSearching$.next(true);
            const results = [];
            const searchStartTime = performance.now();
            if (query != null) {
                query = SearchService.normalizeSearchQuery(query.trim().toLowerCase());
            }
            if (query === "") {
                query = null;
            }
            if (ciphers == null) {
                ciphers = [];
            }
            if (filter != null && Array.isArray(filter) && filter.length > 0) {
                ciphers = ciphers.filter((c) => filter.every((f) => f == null || f(c)));
            }
            else if (filter != null) {
                ciphers = ciphers.filter(filter);
            }
            if (!(yield this.isSearchable(userId, query))) {
                this._isCipherSearching$.next(false);
                return ciphers;
            }
            if (yield this.getIsIndexing(userId)) {
                yield new Promise((r) => setTimeout(r, 250));
                if (yield this.getIsIndexing(userId)) {
                    yield new Promise((r) => setTimeout(r, 500));
                }
            }
            const index = yield this.getIndexForSearch(userId);
            if (index == null) {
                // Fall back to basic search if index is not available
                const basicResults = this.searchCiphersBasic(ciphers, query);
                this.logService.measure(searchStartTime, "Vault", "SearchService", "basic search complete");
                this._isCipherSearching$.next(false);
                return basicResults;
            }
            const ciphersMap = new Map();
            ciphers.forEach((c) => ciphersMap.set(uuidAsString(c.id), c));
            let searchResults = null;
            const isQueryString = query != null && query.length > 1 && query.indexOf(">") === 0;
            if (isQueryString) {
                try {
                    searchResults = index.search(query.substr(1).trim());
                }
                catch (e) {
                    this.logService.error(e);
                }
            }
            else {
                const soWild = external_lunr_namespaceObject.Query.wildcard.LEADING | external_lunr_namespaceObject.Query.wildcard.TRAILING;
                searchResults = index.query((q) => {
                    external_lunr_namespaceObject.tokenizer(query).forEach((token) => {
                        const t = token.toString();
                        q.term(t, { fields: ["name"], wildcard: soWild });
                        q.term(t, { fields: ["subtitle"], wildcard: soWild });
                        q.term(t, { fields: ["login.uris"], wildcard: soWild });
                        q.term(t, {});
                    });
                });
            }
            if (searchResults != null) {
                searchResults.forEach((r) => {
                    if (ciphersMap.has(r.ref)) {
                        results.push(ciphersMap.get(r.ref));
                    }
                });
            }
            this.logService.measure(searchStartTime, "Vault", "SearchService", "search complete");
            this._isCipherSearching$.next(false);
            return results;
        });
    }
    searchCiphersBasic(ciphers, query, deleted = false, archived = false) {
        query = SearchService.normalizeSearchQuery(query.trim().toLowerCase());
        return ciphers.filter((c) => {
            var _a, _b;
            if (deleted !== CipherViewLikeUtils.isDeleted(c)) {
                return false;
            }
            if (archived !== CipherViewLikeUtils.isArchived(c)) {
                return false;
            }
            if (c.name != null && c.name.toLowerCase().indexOf(query) > -1) {
                return true;
            }
            if (query.length >= 8 && uuidAsString(c.id).startsWith(query)) {
                return true;
            }
            const subtitle = CipherViewLikeUtils.subtitle(c);
            if (subtitle != null && subtitle.toLowerCase().indexOf(query) > -1) {
                return true;
            }
            const login = CipherViewLikeUtils.getLogin(c);
            if (login &&
                ((_a = login.uris) === null || _a === void 0 ? void 0 : _a.length) &&
                ((_b = login.uris) === null || _b === void 0 ? void 0 : _b.some((loginUri) => (loginUri === null || loginUri === void 0 ? void 0 : loginUri.uri) && loginUri.uri.toLowerCase().indexOf(query) > -1))) {
                return true;
            }
            return false;
        });
    }
    searchSends(sends, query) {
        this._isSendSearching$.next(true);
        query = SearchService.normalizeSearchQuery(query.trim().toLocaleLowerCase());
        if (query === null) {
            this._isSendSearching$.next(false);
            return sends;
        }
        const sendsMatched = [];
        const lowPriorityMatched = [];
        sends.forEach((s) => {
            var _a, _b, _c;
            if (s.name != null && s.name.toLowerCase().indexOf(query) > -1) {
                sendsMatched.push(s);
            }
            else if (query.length >= 8 &&
                (s.id.startsWith(query) ||
                    s.accessId.toLocaleLowerCase().startsWith(query) ||
                    (((_a = s.file) === null || _a === void 0 ? void 0 : _a.id) != null && s.file.id.startsWith(query)))) {
                lowPriorityMatched.push(s);
            }
            else if (s.notes != null && s.notes.toLowerCase().indexOf(query) > -1) {
                lowPriorityMatched.push(s);
            }
            else if (((_b = s.text) === null || _b === void 0 ? void 0 : _b.text) != null && s.text.text.toLowerCase().indexOf(query) > -1) {
                lowPriorityMatched.push(s);
            }
            else if (((_c = s.file) === null || _c === void 0 ? void 0 : _c.fileName) != null && s.file.fileName.toLowerCase().indexOf(query) > -1) {
                lowPriorityMatched.push(s);
            }
        });
        this._isSendSearching$.next(false);
        return sendsMatched.concat(lowPriorityMatched);
    }
    getIndexForSearch(userId) {
        return search_service_awaiter(this, void 0, void 0, function* () {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.index$(userId));
        });
    }
    setIndexForSearch(userId, index) {
        return search_service_awaiter(this, void 0, void 0, function* () {
            yield this.searchIndexState(userId).update(() => index);
        });
    }
    setIndexedEntityIdForSearch(userId, indexedEntityId) {
        return search_service_awaiter(this, void 0, void 0, function* () {
            yield this.searchIndexEntityIdState(userId).update(() => indexedEntityId);
        });
    }
    setIsIndexing(userId, indexing) {
        return search_service_awaiter(this, void 0, void 0, function* () {
            yield this.searchIsIndexingState(userId).update(() => indexing);
        });
    }
    getIsIndexing(userId) {
        return search_service_awaiter(this, void 0, void 0, function* () {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.searchIsIndexing$(userId));
        });
    }
    fieldExtractor(c, joined) {
        const fields = CipherViewLikeUtils.getFields(c);
        if (!fields || fields.length === 0) {
            return null;
        }
        let fieldStrings = [];
        fields.forEach((f) => {
            if (f.name != null) {
                fieldStrings.push(f.name);
            }
            // For CipherListView, value is only populated for Text fields
            // For CipherView, we check the type explicitly
            if (f.value != null) {
                const fieldType = f.type;
                if (fieldType === undefined || fieldType === FieldType.Text) {
                    fieldStrings.push(f.value);
                }
            }
        });
        fieldStrings = fieldStrings.filter((f) => f.trim() !== "");
        if (fieldStrings.length === 0) {
            return null;
        }
        return joined ? fieldStrings.join(" ") : fieldStrings;
    }
    attachmentExtractor(c, joined) {
        const attachmentNames = CipherViewLikeUtils.getAttachmentNames(c);
        if (!attachmentNames || attachmentNames.length === 0) {
            return null;
        }
        let attachments = [];
        attachmentNames.forEach((fileName) => {
            if (fileName != null) {
                if (joined && fileName.indexOf(".") > -1) {
                    attachments.push(fileName.substring(0, fileName.lastIndexOf(".")));
                }
                else {
                    attachments.push(fileName);
                }
            }
        });
        attachments = attachments.filter((f) => f.trim() !== "");
        if (attachments.length === 0) {
            return null;
        }
        return joined ? attachments.join(" ") : attachments;
    }
    uriExtractor(c) {
        var _a;
        if (CipherViewLikeUtils.getType(c) !== CipherType.Login) {
            return null;
        }
        const login = CipherViewLikeUtils.getLogin(c);
        if (!((_a = login === null || login === void 0 ? void 0 : login.uris) === null || _a === void 0 ? void 0 : _a.length)) {
            return null;
        }
        const uris = [];
        login.uris.forEach((u) => {
            if (u.uri == null || u.uri === "") {
                return;
            }
            // Extract port from URI
            const portMatch = u.uri.match(/:(\d+)(?:[/?#]|$)/);
            const port = portMatch === null || portMatch === void 0 ? void 0 : portMatch[1];
            const hostname = CipherViewLikeUtils.getUriHostname(u);
            if (hostname !== undefined) {
                uris.push(hostname);
                if (port) {
                    uris.push(`${hostname}:${port}`);
                    uris.push(port);
                }
            }
            // Add processed URI (strip protocol and query params for non-regex matches)
            let uri = u.uri;
            if (u.match !== domain_service_UriMatchStrategy.RegularExpression) {
                const protocolIndex = uri.indexOf("://");
                if (protocolIndex > -1) {
                    uri = uri.substring(protocolIndex + 3);
                }
                const queryIndex = uri.search(/\?|&|#/);
                if (queryIndex > -1) {
                    uri = uri.substring(0, queryIndex);
                }
            }
            uris.push(uri);
        });
        return uris.length > 0 ? uris : null;
    }
    normalizeAccentsPipelineFunction(token) {
        const searchableFields = ["name", "login.username", "subtitle", "notes"];
        const fields = token.metadata["fields"];
        const checkFields = fields.every((i) => searchableFields.includes(i));
        if (checkFields) {
            return SearchService.normalizeSearchQuery(token.toString());
        }
        return token;
    }
    // Remove accents/diacritics characters from text. This regex is equivalent to the Diacritic unicode property escape, i.e. it will match all diacritic characters.
    static normalizeSearchQuery(query) {
        return query === null || query === void 0 ? void 0 : query.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
    }
}
SearchService.registeredPipeline = false;

;// ../../libs/common/src/vault/services/totp.service.ts

class TotpService {
    constructor(sdkService) {
        this.sdkService = sdkService;
    }
    getCode$(key) {
        return (0,external_rxjs_namespaceObject.timer)(0, 1000).pipe((0,external_rxjs_namespaceObject.switchMap)(() => this.sdkService.client$.pipe((0,external_rxjs_namespaceObject.map)((sdk) => {
            return sdk.vault().totp().generate_totp(key);
        }))), (0,external_rxjs_namespaceObject.shareReplay)({ refCount: true, bufferSize: 1 }));
    }
}

;// ../../libs/tools/generator/extensions/history/src/generated-password-history.ts
class GeneratedPasswordHistory {
    constructor(password, date) {
        this.password = password;
        this.date = date;
    }
}

;// ../../libs/tools/generator/extensions/history/src/generated-credential.ts
/** A credential generation result */
class src_generated_credential_GeneratedCredential {
    /**
     * Instantiates a generated credential
     * @param credential The value of the generated credential (e.g. a password)
     * @param category The kind of credential
     * @param generationDate The date that the credential was generated.
     *   Numeric values should are interpreted using {@link Date.valueOf}
     *   semantics.
     */
    constructor(credential, category, generationDate) {
        this.credential = credential;
        this.category = category;
        if (typeof generationDate === "number") {
            this.generationDate = new Date(generationDate);
        }
        else {
            this.generationDate = generationDate;
        }
    }
    /** Constructs a credential from its `toJSON` representation */
    static fromJSON(jsonValue) {
        return new src_generated_credential_GeneratedCredential(jsonValue.credential, jsonValue.category, jsonValue.generationDate);
    }
    /** Serializes a credential to a JSON-compatible object */
    toJSON() {
        return {
            credential: this.credential,
            category: this.category,
            generationDate: this.generationDate.valueOf(),
        };
    }
}

;// ../../libs/tools/generator/extensions/history/src/generator-history.abstraction.ts
/** Tracks the history of password generations.
 *  Each user gets their own store.
 */
class GeneratorHistoryService {
}

;// ../../libs/common/src/tools/state/secret-classifier.ts
/** Classifies an object's JSON-serializable data by property into
 *  3 categories:
 *  * Disclosed data MAY be stored in plaintext.
 *  * Excluded data MUST NOT be saved.
 *  * The remaining data is secret and MUST be stored using encryption.
 *
 *  This type should not be used to classify functions.
 *  Data that cannot be serialized by JSON.stringify() should
 *  be excluded.
 */
class SecretClassifier {
    constructor(disclosed, excluded) {
        this.disclosed = disclosed;
        this.excluded = excluded;
    }
    /** Creates a classifier where all properties are secret.
     *  @type {T} The type of secret being classified.
     */
    static allSecret() {
        const disclosed = Object.freeze([]);
        const excluded = Object.freeze([]);
        return new SecretClassifier(disclosed, excluded);
    }
    /** Classify a property as disclosed.
     *  @type {PropertyName} Available secrets to disclose.
     *  @param disclose The property name to disclose.
     *  @returns a new classifier
     */
    disclose(disclose) {
        // update the fluent interface
        const newDisclosed = [...this.disclosed, disclose];
        const classifier = new SecretClassifier(
        // since `NewDisclosed` is opaque to the type checker, it's necessary
        // to assert the type of the array here.
        Object.freeze(newDisclosed), this.excluded);
        return classifier;
    }
    /** Classify a property as excluded.
     *  @type {PropertyName} Available secrets to exclude.
     *  @param exclude The property name to exclude.
     *  @returns a new classifier
     */
    exclude(excludedPropertyName) {
        // update the fluent interface
        const newExcluded = [...this.excluded, excludedPropertyName];
        const classifier = new SecretClassifier(this.disclosed, Object.freeze(newExcluded));
        return classifier;
    }
    /** Partitions `secret` into its disclosed properties and secret properties.
     *  @param value The object to partition
     *  @returns an object that classifies secrets.
     *    The `disclosed` member is new and contains disclosed properties.
     *    The `secret` member is a copy of the secret parameter, including its
     *    prototype, with all disclosed and excluded properties deleted.
     */
    classify(value) {
        // need to JSONify during classification because the prototype is almost guaranteed
        // to be invalid when this  method deletes arbitrary properties.
        const secret = JSON.parse(JSON.stringify(value));
        for (const excludedProp of this.excluded) {
            delete secret[excludedProp];
        }
        const disclosed = {};
        for (const disclosedProp of this.disclosed) {
            // disclosedProp is known to be a subset of the keys of `Plaintext`, so these
            // type assertions are accurate.
            // FIXME: prove it to the compiler
            disclosed[disclosedProp] = secret[disclosedProp];
            delete secret[disclosedProp];
        }
        return {
            disclosed: disclosed,
            secret: secret,
        };
    }
    /** Merges the properties of `secret` and `disclosed`. When `secret` and
     *  `disclosed` contain the same property, the `secret` property overrides
     *  the `disclosed` property.
     *  @param disclosed an object whose disclosed properties are merged into
     *    the output. Unknown properties are ignored.
     *  @param secret an objects whose properties are merged into the output.
     *    Excluded properties are ignored. Unknown properties are retained.
     *  @returns a new object containing the merged data.
     */
    // Declassified data is always jsonified--the purpose of classifying it is to Jsonify it,
    // which causes type conversions.
    declassify(disclosed, secret) {
        // removed unknown keys from `disclosed` to prevent any old edit
        // of plaintext data from being laundered though declassification.
        const cleaned = {};
        for (const disclosedProp of this.disclosed) {
            cleaned[disclosedProp] = disclosed[disclosedProp];
        }
        // merge decrypted into cleaned so that secret data clobbers public data
        const merged = Object.assign(cleaned, secret);
        // delete excluded props
        for (const excludedProp of this.excluded) {
            delete merged[excludedProp];
        }
        return merged;
    }
}

;// ../../libs/tools/generator/extensions/history/src/key-definitions.ts
var key_definitions_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};






/** encrypted password generation history */
const GENERATOR_HISTORY = SecretKeyDefinition.array(GENERATOR_DISK, "localGeneratorHistory", SecretClassifier.allSecret(), {
    deserializer: src_generated_credential_GeneratedCredential.fromJSON,
    clearOn: ["logout"],
});
/** encrypted password generation history subject to migration */
const GENERATOR_HISTORY_BUFFER = new BufferedKeyDefinition(GENERATOR_DISK, "localGeneratorHistoryBuffer", {
    deserializer(history) {
        const items = history;
        return items === null || items === void 0 ? void 0 : items.map((h) => new GeneratedPasswordHistory(h.password, h.date));
    },
    isValid(history) {
        return key_definitions_awaiter(this, void 0, void 0, function* () {
            return history.length ? true : false;
        });
    },
    map(history, decryptor) {
        return key_definitions_awaiter(this, void 0, void 0, function* () {
            const credentials = yield decryptor.decrypt(history);
            const mapped = credentials.map((c) => new src_generated_credential_GeneratedCredential(c.password, "password", c.date));
            return mapped;
        });
    },
    clearOn: ["logout"],
});

;// ../../libs/tools/generator/extensions/history/src/legacy-password-history-decryptor.ts
var legacy_password_history_decryptor_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};



/** Strategy that decrypts a password history */
class LegacyPasswordHistoryDecryptor {
    constructor(userId, keyService, encryptService) {
        this.userId = userId;
        this.keyService = keyService;
        this.encryptService = encryptService;
    }
    /** Decrypts a password history. */
    decrypt(history) {
        return legacy_password_history_decryptor_awaiter(this, void 0, void 0, function* () {
            const key = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.userKey$(this.userId));
            if (key == undefined) {
                throw new Error("No user key found for decryption");
            }
            const promises = (history !== null && history !== void 0 ? history : []).map((item) => legacy_password_history_decryptor_awaiter(this, void 0, void 0, function* () {
                const encrypted = new enc_string_EncString(item.password);
                const decrypted = yield this.encryptService.decryptString(encrypted, key);
                return new GeneratedPasswordHistory(decrypted, item.date);
            }));
            const decrypted = yield Promise.all(promises);
            return decrypted;
        });
    }
}

;// ../../libs/tools/generator/extensions/history/src/local-generator-history.service.ts
var local_generator_history_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore









const local_generator_history_service_OPTIONS_FRAME_SIZE = 2048;
/** Tracks the history of password generations local to a device.
 *  {@link GeneratorHistoryService}
 */
class LocalGeneratorHistoryService extends GeneratorHistoryService {
    constructor(encryptService, keyService, stateProvider, options = { maxTotal: 200 }) {
        super();
        this.encryptService = encryptService;
        this.keyService = keyService;
        this.stateProvider = stateProvider;
        this.options = options;
        this._credentialStates = new Map();
        /** {@link GeneratorHistoryService.track} */
        this.track = (userId, credential, category, date) => local_generator_history_service_awaiter(this, void 0, void 0, function* () {
            const state = this.getCredentialState(userId);
            let result = null;
            yield state.update((credentials) => {
                credentials = credentials !== null && credentials !== void 0 ? credentials : [];
                // add the result
                result = new src_generated_credential_GeneratedCredential(credential, category, date !== null && date !== void 0 ? date : Date.now());
                credentials.unshift(result);
                // trim history
                const removeAt = Math.max(0, this.options.maxTotal);
                credentials.splice(removeAt, Infinity);
                return credentials;
            }, {
                shouldUpdate: (credentials) => { var _a; return !((_a = credentials === null || credentials === void 0 ? void 0 : credentials.some((f) => f.credential === credential)) !== null && _a !== void 0 ? _a : false); },
            });
            return result;
        });
        /** {@link GeneratorHistoryService.take} */
        this.take = (userId, credential) => local_generator_history_service_awaiter(this, void 0, void 0, function* () {
            const state = this.getCredentialState(userId);
            let credentialIndex;
            let result = null;
            yield state.update((credentials) => {
                credentials = credentials !== null && credentials !== void 0 ? credentials : [];
                [result] = credentials.splice(credentialIndex, 1);
                return credentials;
            }, {
                shouldUpdate: (credentials) => {
                    var _a;
                    credentialIndex = (_a = credentials === null || credentials === void 0 ? void 0 : credentials.findIndex((f) => f.credential === credential)) !== null && _a !== void 0 ? _a : -1;
                    return credentialIndex >= 0;
                },
            });
            return result;
        });
        /** {@link GeneratorHistoryService.take} */
        this.clear = (userId) => local_generator_history_service_awaiter(this, void 0, void 0, function* () {
            var _a;
            const state = this.getCredentialState(userId);
            const result = (_a = (yield state.update(() => null))) !== null && _a !== void 0 ? _a : [];
            return result;
        });
        /** {@link GeneratorHistoryService.credentials$} */
        this.credentials$ = (userId) => {
            return this.getCredentialState(userId).state$.pipe((0,external_rxjs_namespaceObject.map)((credentials) => credentials !== null && credentials !== void 0 ? credentials : []));
        };
    }
    getCredentialState(userId) {
        let state = this._credentialStates.get(userId);
        if (!state) {
            state = this.createSecretState(userId);
            this._credentialStates.set(userId, state);
        }
        return state;
    }
    createSecretState(userId) {
        // construct the encryptor
        const packer = new PaddedDataPacker(local_generator_history_service_OPTIONS_FRAME_SIZE);
        const encryptor$ = this.keyService.userKey$(userId).pipe((0,external_rxjs_namespaceObject.map)((key) => (key ? new UserKeyEncryptor(userId, this.encryptService, key, packer) : null)), (0,external_rxjs_namespaceObject.filter)((encryptor) => !!encryptor));
        // construct the durable state
        const state = SecretState.from(userId, GENERATOR_HISTORY, this.stateProvider, encryptor$);
        // decryptor is just an algorithm, but it can't run until the key is available;
        // providing it via an observable makes running it early impossible
        const decryptor = new LegacyPasswordHistoryDecryptor(userId, this.keyService, this.encryptService);
        const decryptor$ = this.keyService.userKey$(userId).pipe((0,external_rxjs_namespaceObject.map)((key) => key && decryptor));
        // move data from the old password history once decryptor is available
        const buffer = new BufferedState(this.stateProvider, GENERATOR_HISTORY_BUFFER, state, decryptor$);
        return buffer;
    }
}

;// ../../libs/tools/generator/extensions/history/src/index.ts





;// ../../libs/tools/generator/extensions/navigation/src/default-generator-navigation.ts
/** The default options for password generation. */
const DefaultGeneratorNavigation = Object.freeze({
    type: "password",
    username: "word",
    forwarder: "",
});

;// ../../libs/tools/generator/extensions/navigation/src/generator-navigation-evaluator.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


/** Enforces policy for generator navigation options.
 */
class GeneratorNavigationEvaluator {
    /** Instantiates the evaluator.
     * @param policy The policy applied by the evaluator. When this conflicts with
     *               the defaults, the policy takes precedence.
     */
    constructor(policy) {
        this.policy = policy;
    }
    /** {@link PolicyEvaluator.policyInEffect} */
    get policyInEffect() {
        var _a;
        return metadata_AlgorithmsByType[data_Type.password].includes((_a = this.policy) === null || _a === void 0 ? void 0 : _a.overridePasswordType);
    }
    /** Apply policy to the input options.
     *  @param options The options to build from. These options are not altered.
     *  @returns A new password generation request with policy applied.
     */
    applyPolicy(options) {
        var _a;
        const result = Object.assign({}, options);
        if (this.policyInEffect) {
            result.type = (_a = this.policy.overridePasswordType) !== null && _a !== void 0 ? _a : result.type;
        }
        return result;
    }
    /** Ensures internal options consistency.
     *  @param options The options to cascade. These options are not altered.
     *  @returns A passphrase generation request with cascade applied.
     */
    sanitize(options) {
        var _a;
        return Object.assign(Object.assign({}, options), { type: (_a = options.type) !== null && _a !== void 0 ? _a : DefaultGeneratorNavigation.type });
    }
}

;// ../../libs/tools/generator/extensions/navigation/src/generator-navigation-policy.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

/** Reduces a policy into an accumulator by preferring the password generator
 *  type to other generator types.
 *  @param acc the accumulator
 *  @param policy the policy to reduce
 *  @returns the resulting `GeneratorNavigationPolicy`
 */
function preferPassword(acc, policy) {
    const isEnabled = policy.type === policy_type_enum_PolicyType.PasswordGenerator && policy.enabled;
    if (!isEnabled) {
        return acc;
    }
    const isOverridable = acc.overridePasswordType !== "password" && policy.data.overridePasswordType;
    const result = isOverridable
        ? Object.assign(Object.assign({}, acc), { overridePasswordType: policy.data.overridePasswordType }) : acc;
    return result;
}
/** The default options for password generation policy. */
const DisabledGeneratorNavigationPolicy = Object.freeze({
    overridePasswordType: null,
});

;// ../../libs/tools/generator/extensions/navigation/src/key-definitions.ts

/** plaintext password generation options */
const GENERATOR_SETTINGS = new UserKeyDefinition(GENERATOR_DISK, "generatorSettings", {
    deserializer: (value) => value,
    clearOn: ["logout"],
});

;// ../../libs/tools/generator/extensions/navigation/src/default-generator-navigation.service.ts
var default_generator_navigation_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};







class default_generator_navigation_service_DefaultGeneratorNavigationService {
    /** instantiates the password generator strategy.
     * @param stateProvider provides durable state
     * @param policy provides the policy to enforce
     */
    constructor(stateProvider, policy) {
        this.stateProvider = stateProvider;
        this.policy = policy;
    }
    /** An observable monitoring the options saved to disk.
     *  The observable updates when the options are saved.
     *   @param userId: Identifies the user making the request
     */
    options$(userId) {
        return this.stateProvider.getUserState$(GENERATOR_SETTINGS, userId);
    }
    /** Gets the default options. */
    defaults$(userId) {
        return new external_rxjs_namespaceObject.BehaviorSubject(Object.assign({}, DefaultGeneratorNavigation));
    }
    /** An observable monitoring the options used to enforce policy.
     *  The observable updates when the policy changes.
     *  @param userId: Identifies the user making the request
     */
    evaluator$(userId) {
        const evaluator$ = this.policy.policiesByType$(policy_type_enum_PolicyType.PasswordGenerator, userId).pipe(reduceCollection(preferPassword, DisabledGeneratorNavigationPolicy), distinctIfShallowMatch(), (0,external_rxjs_namespaceObject.map)((policy) => new GeneratorNavigationEvaluator(policy)));
        return evaluator$;
    }
    /** Enforces the policy on the given options
     * @param userId: Identifies the user making the request
     * @param options the options to enforce the policy on
     * @returns a new instance of the options with the policy enforced
     */
    enforcePolicy(userId, options) {
        return default_generator_navigation_service_awaiter(this, void 0, void 0, function* () {
            const evaluator = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.evaluator$(userId));
            const applied = evaluator.applyPolicy(options);
            const sanitized = evaluator.sanitize(applied);
            return sanitized;
        });
    }
    /** Saves the navigation options to disk.
     * @param userId: Identifies the user making the request
     * @param options the options to save
     * @returns a promise that resolves when the options are saved
     */
    saveOptions(userId, options) {
        return default_generator_navigation_service_awaiter(this, void 0, void 0, function* () {
            yield this.stateProvider.setUserState(GENERATOR_SETTINGS, options, userId);
        });
    }
}

;// ../../libs/tools/generator/extensions/navigation/src/index.ts





;// ../../libs/common/src/admin-console/models/domain/password-generator-policy-options.ts

/** Enterprise policy for the password generator.
 * @see PolicyType.PasswordGenerator
 */
class PasswordGeneratorPolicyOptions extends Domain {
    constructor() {
        super(...arguments);
        /** The default kind of credential to generate */
        this.overridePasswordType = "";
        /** The minimum length of generated passwords.
         *  When this is less than or equal to zero, it is ignored.
         *  If this is less than the total number of characters required by
         *  the policy's other settings, then it is ignored.
         *  This field is not used for passphrases.
         */
        this.minLength = 0;
        /** When this is true, an uppercase character must be part of
         *  the generated password.
         *  This field is not used for passphrases.
         */
        this.useUppercase = false;
        /** When this is true, a lowercase character must be part of
         *  the generated password. This field is not used for passphrases.
         */
        this.useLowercase = false;
        /** When this is true, at least one digit must be part of the generated
         *  password. This field is not used for passphrases.
         */
        this.useNumbers = false;
        /** The quantity of digits to include in the generated password.
         *  When this is less than or equal to zero, it is ignored.
         *  This field is not used for passphrases.
         */
        this.numberCount = 0;
        /** When this is true, at least one digit must be part of the generated
         *  password. This field is not used for passphrases.
         */
        this.useSpecial = false;
        /** The quantity of special characters to include in the generated
         *  password. When this is less than or equal to zero, it is ignored.
         *  This field is not used for passphrases.
         */
        this.specialCount = 0;
        /** The minimum number of words required by generated passphrases.
         *  This field is not used for passwords.
         */
        this.minNumberWords = 0;
        /** When this is true, the first letter of each word in the passphrase
         *  is capitalized. This field is not used for passwords.
         */
        this.capitalize = false;
        /** When this is true, a number is included within the passphrase.
         *  This field is not used for passwords.
         */
        this.includeNumber = false;
    }
    /** Checks whether the policy affects the password generator.
     * @returns True if at least one password or passphrase requirement has been set.
     * If it returns False, then no requirements have been set and the policy should
     * not be enforced.
     */
    inEffect() {
        return (this.overridePasswordType ||
            this.minLength > 0 ||
            this.numberCount > 0 ||
            this.specialCount > 0 ||
            this.useUppercase ||
            this.useLowercase ||
            this.useNumbers ||
            this.useSpecial ||
            this.minNumberWords > 0 ||
            this.capitalize ||
            this.includeNumber);
    }
    /** Creates a copy of the policy.
     */
    clone() {
        const policy = new PasswordGeneratorPolicyOptions();
        Object.assign(policy, this);
        return policy;
    }
}

;// ../../libs/tools/generator/extensions/legacy/src/legacy-password-generation.service.ts
var legacy_password_generation_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore



/** Adapts the generator 2.0 design to 1.0 angular services. */
class LegacyPasswordGenerationService {
    constructor(accountService, navigation, passwords, passphrases, history) {
        this.accountService = accountService;
        this.navigation = navigation;
        this.passwords = passwords;
        this.passphrases = passphrases;
        this.history = history;
    }
    generatePassword(options) {
        if (options.type === "password") {
            return this.passwords.generate(options);
        }
        else {
            return this.passphrases.generate(options);
        }
    }
    generatePassphrase(options) {
        return this.passphrases.generate(options);
    }
    getRawOptions$() {
        function withSequenceNumber(observable$) {
            return observable$.pipe((0,external_rxjs_namespaceObject.map)((evaluator, i) => [evaluator, i]));
        }
        // initial array ensures that destructuring never fails; sequence numbers
        // set to `-1` so that the first update reflects that the policy changed from
        // "unknown" to "whatever was provided by the service". This needs to be called
        // each time the active user changes or the `concat` will block.
        function initial$() {
            const initial = [
                null,
                null,
                [null, -1],
                null,
                null,
                [null, -1],
                null,
                null,
                [null, -1],
            ];
            return (0,external_rxjs_namespaceObject.of)(initial);
        }
        function intermediatePairsToRawOptions([previous, current]) {
            const [, , [, passwordPrevious], , , [, passphrasePrevious], , , [, generatorPrevious]] = previous;
            const [passwordOptions, passwordDefaults, [passwordEvaluator, passwordCurrent], passphraseOptions, passphraseDefaults, [passphraseEvaluator, passphraseCurrent], generatorOptions, generatorDefaults, [generatorEvaluator, generatorCurrent],] = current;
            // when any of the sequence numbers change, the emission occurs as the result of
            // a policy update
            const policyEmitted = passwordPrevious < passwordCurrent ||
                passphrasePrevious < passphraseCurrent ||
                generatorPrevious < generatorCurrent;
            const result = [
                passwordOptions,
                passwordDefaults,
                passwordEvaluator,
                passphraseOptions,
                passphraseDefaults,
                passphraseEvaluator,
                generatorOptions,
                generatorDefaults,
                generatorEvaluator,
                policyEmitted,
            ];
            return result;
        }
        // look upon my works, ye mighty, and despair!
        const rawOptions$ = this.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.concatMap)((activeUser) => (0,external_rxjs_namespaceObject.concat)(initial$(), (0,external_rxjs_namespaceObject.combineLatest)([
            this.passwords.options$(activeUser.id),
            this.passwords.defaults$(activeUser.id),
            withSequenceNumber(this.passwords.evaluator$(activeUser.id)),
            this.passphrases.options$(activeUser.id),
            this.passphrases.defaults$(activeUser.id),
            withSequenceNumber(this.passphrases.evaluator$(activeUser.id)),
            this.navigation.options$(activeUser.id),
            this.navigation.defaults$(activeUser.id),
            withSequenceNumber(this.navigation.evaluator$(activeUser.id)),
        ]))), (0,external_rxjs_namespaceObject.pairwise)(), (0,external_rxjs_namespaceObject.map)(intermediatePairsToRawOptions));
        return rawOptions$;
    }
    getOptions$() {
        const options$ = this.getRawOptions$().pipe((0,external_rxjs_namespaceObject.map)(([passwordOptions, passwordDefaults, passwordEvaluator, passphraseOptions, passphraseDefaults, passphraseEvaluator, generatorOptions, generatorDefaults, generatorEvaluator, policyUpdated,]) => {
            const passwordOptionsWithPolicy = passwordEvaluator.applyPolicy(passwordOptions !== null && passwordOptions !== void 0 ? passwordOptions : passwordDefaults);
            const passphraseOptionsWithPolicy = passphraseEvaluator.applyPolicy(passphraseOptions !== null && passphraseOptions !== void 0 ? passphraseOptions : passphraseDefaults);
            const generatorOptionsWithPolicy = generatorEvaluator.applyPolicy(generatorOptions !== null && generatorOptions !== void 0 ? generatorOptions : generatorDefaults);
            const options = this.toPasswordGeneratorOptions({
                password: passwordEvaluator.sanitize(passwordOptionsWithPolicy),
                passphrase: passphraseEvaluator.sanitize(passphraseOptionsWithPolicy),
                generator: generatorEvaluator.sanitize(generatorOptionsWithPolicy),
                policyUpdated,
            });
            const policy = Object.assign(new PasswordGeneratorPolicyOptions(), passwordEvaluator.policy, passphraseEvaluator.policy, generatorEvaluator.policy);
            return [options, policy];
        }));
        return options$;
    }
    getOptions() {
        return legacy_password_generation_service_awaiter(this, void 0, void 0, function* () {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.getOptions$());
        });
    }
    enforcePasswordGeneratorPoliciesOnOptions(options) {
        return legacy_password_generation_service_awaiter(this, void 0, void 0, function* () {
            const options$ = this.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.concatMap)((activeUser) => (0,external_rxjs_namespaceObject.zip)(this.passwords.evaluator$(activeUser.id), this.passphrases.evaluator$(activeUser.id), this.navigation.evaluator$(activeUser.id))), (0,external_rxjs_namespaceObject.map)(([passwordEvaluator, passphraseEvaluator, navigationEvaluator]) => {
                const policy = Object.assign(new PasswordGeneratorPolicyOptions(), passwordEvaluator.policy, passphraseEvaluator.policy, navigationEvaluator.policy);
                const navigationApplied = navigationEvaluator.applyPolicy(options);
                const navigationSanitized = Object.assign(Object.assign({}, options), navigationEvaluator.sanitize(navigationApplied));
                if (navigationSanitized.type === "password") {
                    const applied = passwordEvaluator.applyPolicy(navigationSanitized);
                    const sanitized = passwordEvaluator.sanitize(applied);
                    return [sanitized, policy];
                }
                else {
                    const applied = passphraseEvaluator.applyPolicy(navigationSanitized);
                    const sanitized = passphraseEvaluator.sanitize(applied);
                    return [sanitized, policy];
                }
            }));
            const [sanitized, policy] = yield (0,external_rxjs_namespaceObject.firstValueFrom)(options$);
            return [
                // callers assume this function updates the options parameter
                Object.assign(options, sanitized),
                policy,
            ];
        });
    }
    saveOptions(options) {
        return legacy_password_generation_service_awaiter(this, void 0, void 0, function* () {
            const stored = this.toStoredOptions(options);
            const activeAccount = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$);
            // generator settings needs to preserve whether password or passphrase is selected,
            // so `navigationOptions` is mutated.
            const navigationOptions$ = (0,external_rxjs_namespaceObject.zip)(this.navigation.options$(activeAccount.id), this.navigation.defaults$(activeAccount.id)).pipe((0,external_rxjs_namespaceObject.map)(([options, defaults]) => options !== null && options !== void 0 ? options : defaults));
            let navigationOptions = yield (0,external_rxjs_namespaceObject.firstValueFrom)(navigationOptions$);
            navigationOptions = Object.assign(navigationOptions, stored.generator);
            yield this.navigation.saveOptions(activeAccount.id, navigationOptions);
            // overwrite all other settings with latest values
            yield this.passwords.saveOptions(activeAccount.id, stored.password);
            yield this.passphrases.saveOptions(activeAccount.id, stored.passphrase);
        });
    }
    toStoredOptions(options) {
        return {
            generator: {
                type: options.type,
            },
            password: {
                length: options.length,
                minLength: options.minLength,
                ambiguous: options.ambiguous,
                uppercase: options.uppercase,
                minUppercase: options.minUppercase,
                lowercase: options.lowercase,
                minLowercase: options.minLowercase,
                number: options.number,
                minNumber: options.minNumber,
                special: options.special,
                minSpecial: options.minSpecial,
            },
            passphrase: {
                numWords: options.numWords,
                wordSeparator: options.wordSeparator,
                capitalize: options.capitalize,
                includeNumber: options.includeNumber,
            },
            policyUpdated: false,
        };
    }
    toPasswordGeneratorOptions(options) {
        return {
            type: options.generator.type,
            length: options.password.length,
            minLength: options.password.minLength,
            ambiguous: options.password.ambiguous,
            uppercase: options.password.uppercase,
            minUppercase: options.password.minUppercase,
            lowercase: options.password.lowercase,
            minLowercase: options.password.minLowercase,
            number: options.password.number,
            minNumber: options.password.minNumber,
            special: options.password.special,
            minSpecial: options.password.minSpecial,
            numWords: options.passphrase.numWords,
            wordSeparator: options.passphrase.wordSeparator,
            capitalize: options.passphrase.capitalize,
            includeNumber: options.passphrase.includeNumber,
            policyUpdated: options.policyUpdated,
        };
    }
    getHistory() {
        const history = this.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.concatMap)((account) => this.history.credentials$(account.id)), (0,external_rxjs_namespaceObject.timeout)({
            // timeout after 1 second
            each: 1000,
            // TODO(PM-22309): Typescript 5.8 update, confirm type
            with() {
                return [];
            },
        }), (0,external_rxjs_namespaceObject.map)((history) => history.map(toGeneratedPasswordHistory)));
        return (0,external_rxjs_namespaceObject.firstValueFrom)(history);
    }
    addHistory(password) {
        return legacy_password_generation_service_awaiter(this, void 0, void 0, function* () {
            const account = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$);
            if (account === null || account === void 0 ? void 0 : account.id) {
                // legacy service doesn't distinguish credential types
                yield this.history.track(account.id, password, "password");
            }
        });
    }
    clear() {
        const history$ = this.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.filter)((account) => !!(account === null || account === void 0 ? void 0 : account.id)), (0,external_rxjs_namespaceObject.concatMap)((account) => this.history.clear(account.id)), (0,external_rxjs_namespaceObject.timeout)({
            // timeout after 1 second
            each: 1000,
            // TODO(PM-22309): Typescript 5.8 update, confirm type
            with() {
                return [];
            },
        }), (0,external_rxjs_namespaceObject.map)((history) => history.map(toGeneratedPasswordHistory)));
        return (0,external_rxjs_namespaceObject.firstValueFrom)(history$);
    }
}
function toGeneratedPasswordHistory(value) {
    return new GeneratedPasswordHistory(value.credential, value.generationDate.valueOf());
}

;// ../../libs/tools/generator/extensions/legacy/src/create-legacy-password-generation-service.ts




const { /* PassphraseGeneratorStrategy */ "jK": create_legacy_password_generation_service_PassphraseGeneratorStrategy, /* PasswordGeneratorStrategy */ "gb": create_legacy_password_generation_service_PasswordGeneratorStrategy } = strategies_namespaceObject;
const { /* PureCryptoRandomizer */ "f3": create_legacy_password_generation_service_PureCryptoRandomizer, /* PasswordRandomizer */ "Zx": create_legacy_password_generation_service_PasswordRandomizer } = engine_namespaceObject;
const create_legacy_password_generation_service_DefaultGeneratorService = DefaultGeneratorService;
function legacyPasswordGenerationServiceFactory(encryptService, keyService, policyService, accountService, stateProvider) {
    const randomizer = new create_legacy_password_generation_service_PureCryptoRandomizer();
    const passwordRandomizer = new create_legacy_password_generation_service_PasswordRandomizer(randomizer, Date.now);
    const passwords = new create_legacy_password_generation_service_DefaultGeneratorService(new create_legacy_password_generation_service_PasswordGeneratorStrategy(passwordRandomizer, stateProvider), policyService);
    const passphrases = new create_legacy_password_generation_service_DefaultGeneratorService(new create_legacy_password_generation_service_PassphraseGeneratorStrategy(passwordRandomizer, stateProvider), policyService);
    const navigation = new default_generator_navigation_service_DefaultGeneratorNavigationService(stateProvider, policyService);
    const history = new LocalGeneratorHistoryService(encryptService, keyService, stateProvider);
    return new LegacyPasswordGenerationService(accountService, navigation, passwords, passphrases, history);
}

;// ../../libs/tools/generator/extensions/legacy/src/forwarders.ts
/** Metadata about an email forwarding service.
 *  @remarks This is used to populate the forwarder selection list
 *  and to identify forwarding services in error messages.
 */
const forwarders_Forwarders = Object.freeze({
    /** For https://addy.io/ */
    AddyIo: Object.freeze({
        id: "anonaddy",
        name: "Addy.io",
        validForSelfHosted: true,
    }),
    /** For https://duckduckgo.com/email/ */
    DuckDuckGo: Object.freeze({
        id: "duckduckgo",
        name: "DuckDuckGo",
        validForSelfHosted: false,
    }),
    /** For https://www.fastmail.com. */
    Fastmail: Object.freeze({
        id: "fastmail",
        name: "Fastmail",
        validForSelfHosted: true,
    }),
    /** For https://relay.firefox.com/ */
    FirefoxRelay: Object.freeze({
        id: "firefoxrelay",
        name: "Firefox Relay",
        validForSelfHosted: false,
    }),
    /** For https://forwardemail.net/ */
    ForwardEmail: Object.freeze({
        id: "forwardemail",
        name: "Forward Email",
        validForSelfHosted: true,
    }),
    /** For https://simplelogin.io/ */
    SimpleLogin: Object.freeze({
        id: "simplelogin",
        name: "SimpleLogin",
        validForSelfHosted: true,
    }),
});

;// ../../libs/tools/generator/extensions/legacy/src/legacy-username-generation.service.ts
var legacy_username_generation_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore



/** Adapts the generator 2.0 design to 1.0 angular services. */
class legacy_username_generation_service_LegacyUsernameGenerationService {
    constructor(accountService, navigation, catchall, effUsername, subaddress, addyIo, duckDuckGo, fastmail, firefoxRelay, forwardEmail, simpleLogin) {
        this.accountService = accountService;
        this.navigation = navigation;
        this.catchall = catchall;
        this.effUsername = effUsername;
        this.subaddress = subaddress;
        this.addyIo = addyIo;
        this.duckDuckGo = duckDuckGo;
        this.fastmail = fastmail;
        this.firefoxRelay = firefoxRelay;
        this.forwardEmail = forwardEmail;
        this.simpleLogin = simpleLogin;
    }
    generateUsername(options) {
        if (options.type === "catchall") {
            return this.generateCatchall(options);
        }
        else if (options.type === "subaddress") {
            return this.generateSubaddress(options);
        }
        else if (options.type === "forwarded") {
            return this.generateForwarded(options);
        }
        else {
            return this.generateWord(options);
        }
    }
    generateWord(options) {
        return this.effUsername.generate(options);
    }
    generateSubaddress(options) {
        return this.subaddress.generate(options);
    }
    generateCatchall(options) {
        return this.catchall.generate(options);
    }
    generateForwarded(options) {
        if (!options.forwardedService) {
            return null;
        }
        const stored = this.toStoredOptions(options);
        switch (options.forwardedService) {
            case Forwarders.AddyIo.id:
            case Vendor.addyio:
                return this.addyIo.generate(stored.forwarders.addyIo);
            case Forwarders.DuckDuckGo.id:
                return this.duckDuckGo.generate(stored.forwarders.duckDuckGo);
            case Forwarders.Fastmail.id:
                return this.fastmail.generate(stored.forwarders.fastmail);
            case Forwarders.FirefoxRelay.id:
            case Vendor.mozilla:
                return this.firefoxRelay.generate(stored.forwarders.firefoxRelay);
            case Forwarders.ForwardEmail.id:
                return this.forwardEmail.generate(stored.forwarders.forwardEmail);
            case Forwarders.SimpleLogin.id:
                return this.simpleLogin.generate(stored.forwarders.simpleLogin);
        }
    }
    getOptions$() {
        // look upon my works, ye mighty, and despair!
        const options$ = this.accountService.activeAccount$.pipe(concatMap((account) => combineLatest([
            this.navigation.options$(account.id),
            this.navigation.defaults$(account.id),
            this.catchall.options$(account.id),
            this.catchall.defaults$(account.id),
            this.effUsername.options$(account.id),
            this.effUsername.defaults$(account.id),
            this.subaddress.options$(account.id),
            this.subaddress.defaults$(account.id),
            this.addyIo.options$(account.id),
            this.addyIo.defaults$(account.id),
            this.duckDuckGo.options$(account.id),
            this.duckDuckGo.defaults$(account.id),
            this.fastmail.options$(account.id),
            this.fastmail.defaults$(account.id),
            this.firefoxRelay.options$(account.id),
            this.firefoxRelay.defaults$(account.id),
            this.forwardEmail.options$(account.id),
            this.forwardEmail.defaults$(account.id),
            this.simpleLogin.options$(account.id),
            this.simpleLogin.defaults$(account.id),
        ])), map(([generatorOptions, generatorDefaults, catchallOptions, catchallDefaults, effUsernameOptions, effUsernameDefaults, subaddressOptions, subaddressDefaults, addyIoOptions, addyIoDefaults, duckDuckGoOptions, duckDuckGoDefaults, fastmailOptions, fastmailDefaults, firefoxRelayOptions, firefoxRelayDefaults, forwardEmailOptions, forwardEmailDefaults, simpleLoginOptions, simpleLoginDefaults,]) => this.toUsernameOptions({
            generator: generatorOptions !== null && generatorOptions !== void 0 ? generatorOptions : generatorDefaults,
            algorithms: {
                catchall: catchallOptions !== null && catchallOptions !== void 0 ? catchallOptions : catchallDefaults,
                effUsername: effUsernameOptions !== null && effUsernameOptions !== void 0 ? effUsernameOptions : effUsernameDefaults,
                subaddress: subaddressOptions !== null && subaddressOptions !== void 0 ? subaddressOptions : subaddressDefaults,
            },
            forwarders: {
                addyIo: addyIoOptions !== null && addyIoOptions !== void 0 ? addyIoOptions : addyIoDefaults,
                duckDuckGo: duckDuckGoOptions !== null && duckDuckGoOptions !== void 0 ? duckDuckGoOptions : duckDuckGoDefaults,
                fastmail: fastmailOptions !== null && fastmailOptions !== void 0 ? fastmailOptions : fastmailDefaults,
                firefoxRelay: firefoxRelayOptions !== null && firefoxRelayOptions !== void 0 ? firefoxRelayOptions : firefoxRelayDefaults,
                forwardEmail: forwardEmailOptions !== null && forwardEmailOptions !== void 0 ? forwardEmailOptions : forwardEmailDefaults,
                simpleLogin: simpleLoginOptions !== null && simpleLoginOptions !== void 0 ? simpleLoginOptions : simpleLoginDefaults,
            },
        })));
        return options$;
    }
    getOptions() {
        return firstValueFrom(this.getOptions$());
    }
    saveOptions(options) {
        return legacy_username_generation_service_awaiter(this, void 0, void 0, function* () {
            const stored = this.toStoredOptions(options);
            const activeAccount = yield firstValueFrom(this.accountService.activeAccount$);
            const saved = yield this.saveGeneratorOptions(activeAccount.id, options.type, stored);
            if (!saved) {
                yield this.saveForwarderOptions(activeAccount.id, options.forwardedService, stored);
            }
            // run navigation options 2nd so that navigation options update doesn't race the `saved options`
            // update in Firefox.
            yield this.saveNavigationOptions(activeAccount.id, stored);
        });
    }
    saveNavigationOptions(account, options) {
        return legacy_username_generation_service_awaiter(this, void 0, void 0, function* () {
            // generator settings needs to preserve whether password or passphrase is selected,
            // so `navigationOptions` is mutated.
            const navigationOptions$ = zip(this.navigation.options$(account), this.navigation.defaults$(account)).pipe(map(([options, defaults]) => options !== null && options !== void 0 ? options : defaults));
            let navigationOptions = yield firstValueFrom(navigationOptions$);
            navigationOptions = Object.assign(navigationOptions, options.generator);
            yield this.navigation.saveOptions(account, navigationOptions);
        });
    }
    saveGeneratorOptions(account, type, options) {
        return legacy_username_generation_service_awaiter(this, void 0, void 0, function* () {
            switch (type) {
                case "word":
                    yield this.effUsername.saveOptions(account, options.algorithms.effUsername);
                    return true;
                case "subaddress":
                    yield this.subaddress.saveOptions(account, options.algorithms.subaddress);
                    return true;
                case "catchall":
                    yield this.catchall.saveOptions(account, options.algorithms.catchall);
                    return true;
                default:
                    return false;
            }
        });
    }
    saveForwarderOptions(account, forwarder, options) {
        return legacy_username_generation_service_awaiter(this, void 0, void 0, function* () {
            switch (forwarder) {
                case Forwarders.AddyIo.id:
                case Vendor.addyio:
                    yield this.addyIo.saveOptions(account, options.forwarders.addyIo);
                    return true;
                case Forwarders.DuckDuckGo.id:
                    yield this.duckDuckGo.saveOptions(account, options.forwarders.duckDuckGo);
                    return true;
                case Forwarders.Fastmail.id:
                    yield this.fastmail.saveOptions(account, options.forwarders.fastmail);
                    return true;
                case Forwarders.FirefoxRelay.id:
                case Vendor.mozilla:
                    yield this.firefoxRelay.saveOptions(account, options.forwarders.firefoxRelay);
                    return true;
                case Forwarders.ForwardEmail.id:
                    yield this.forwardEmail.saveOptions(account, options.forwarders.forwardEmail);
                    return true;
                case Forwarders.SimpleLogin.id:
                    yield this.simpleLogin.saveOptions(account, options.forwarders.simpleLogin);
                    return true;
                default:
                    return false;
            }
        });
    }
    toStoredOptions(options) {
        const forwarders = {
            addyIo: {
                baseUrl: options.forwardedAnonAddyBaseUrl,
                token: options.forwardedAnonAddyApiToken,
                domain: options.forwardedAnonAddyDomain,
                website: options.website,
            },
            duckDuckGo: {
                token: options.forwardedDuckDuckGoToken,
                website: options.website,
            },
            fastmail: {
                token: options.forwardedFastmailApiToken,
                website: options.website,
            },
            firefoxRelay: {
                token: options.forwardedFirefoxApiToken,
                website: options.website,
            },
            forwardEmail: {
                token: options.forwardedForwardEmailApiToken,
                domain: options.forwardedForwardEmailDomain,
                website: options.website,
            },
            simpleLogin: {
                token: options.forwardedSimpleLoginApiKey,
                baseUrl: options.forwardedSimpleLoginBaseUrl,
                website: options.website,
            },
        };
        const generator = {
            username: options.type,
            forwarder: options.forwardedService,
        };
        const algorithms = {
            effUsername: {
                wordCapitalize: options.wordCapitalize,
                wordIncludeNumber: options.wordIncludeNumber,
                website: options.website,
            },
            subaddress: {
                subaddressType: options.subaddressType,
                subaddressEmail: options.subaddressEmail,
                website: options.website,
            },
            catchall: {
                catchallType: options.catchallType,
                catchallDomain: options.catchallDomain,
                website: options.website,
            },
        };
        return { generator, algorithms, forwarders };
    }
    toUsernameOptions(options) {
        return {
            type: options.generator.username,
            wordCapitalize: options.algorithms.effUsername.wordCapitalize,
            wordIncludeNumber: options.algorithms.effUsername.wordIncludeNumber,
            subaddressType: options.algorithms.subaddress.subaddressType,
            subaddressEmail: options.algorithms.subaddress.subaddressEmail,
            catchallType: options.algorithms.catchall.catchallType,
            catchallDomain: options.algorithms.catchall.catchallDomain,
            forwardedService: options.generator.forwarder,
            forwardedAnonAddyApiToken: options.forwarders.addyIo.token,
            forwardedAnonAddyDomain: options.forwarders.addyIo.domain,
            forwardedAnonAddyBaseUrl: options.forwarders.addyIo.baseUrl,
            forwardedDuckDuckGoToken: options.forwarders.duckDuckGo.token,
            forwardedFirefoxApiToken: options.forwarders.firefoxRelay.token,
            forwardedFastmailApiToken: options.forwarders.fastmail.token,
            forwardedForwardEmailApiToken: options.forwarders.forwardEmail.token,
            forwardedForwardEmailDomain: options.forwarders.forwardEmail.domain,
            forwardedSimpleLoginApiKey: options.forwarders.simpleLogin.token,
            forwardedSimpleLoginBaseUrl: options.forwarders.simpleLogin.baseUrl,
        };
    }
}

;// ../../libs/tools/generator/extensions/legacy/src/create-legacy-username-generation-service.ts




const { /* PureCryptoRandomizer */ "f3": create_legacy_username_generation_service_PureCryptoRandomizer, /* UsernameRandomizer */ "QS": create_legacy_username_generation_service_UsernameRandomizer, /* EmailRandomizer */ "Mt": create_legacy_username_generation_service_EmailRandomizer, /* EmailCalculator */ "Lq": create_legacy_username_generation_service_EmailCalculator } = engine_namespaceObject;
const create_legacy_username_generation_service_DefaultGeneratorService = DefaultGeneratorService;
const { /* CatchallGeneratorStrategy */ "B": create_legacy_username_generation_service_CatchallGeneratorStrategy, /* SubaddressGeneratorStrategy */ "Vm": create_legacy_username_generation_service_SubaddressGeneratorStrategy, /* EffUsernameGeneratorStrategy */ "KQ": create_legacy_username_generation_service_EffUsernameGeneratorStrategy, /* ForwarderGeneratorStrategy */ "ji": create_legacy_username_generation_service_ForwarderGeneratorStrategy, } = strategies_namespaceObject;
function legacyUsernameGenerationServiceFactory(apiService, i18nService, keyService, encryptService, policyService, accountService, stateProvider) {
    const randomizer = new create_legacy_username_generation_service_PureCryptoRandomizer();
    const restClient = new RestClient(apiService, i18nService);
    const usernameRandomizer = new create_legacy_username_generation_service_UsernameRandomizer(randomizer);
    const emailRandomizer = new create_legacy_username_generation_service_EmailRandomizer(randomizer);
    const emailCalculator = new create_legacy_username_generation_service_EmailCalculator();
    const effUsername = new create_legacy_username_generation_service_DefaultGeneratorService(new create_legacy_username_generation_service_EffUsernameGeneratorStrategy(usernameRandomizer, stateProvider), policyService);
    const subaddress = new create_legacy_username_generation_service_DefaultGeneratorService(new create_legacy_username_generation_service_SubaddressGeneratorStrategy(emailCalculator, emailRandomizer, stateProvider), policyService);
    const catchall = new create_legacy_username_generation_service_DefaultGeneratorService(new create_legacy_username_generation_service_CatchallGeneratorStrategy(emailCalculator, emailRandomizer, stateProvider), policyService);
    const addyIo = new create_legacy_username_generation_service_DefaultGeneratorService(new create_legacy_username_generation_service_ForwarderGeneratorStrategy(Integrations.AddyIo, restClient, i18nService, encryptService, keyService, stateProvider), policyService);
    const duckDuckGo = new create_legacy_username_generation_service_DefaultGeneratorService(new create_legacy_username_generation_service_ForwarderGeneratorStrategy(Integrations.DuckDuckGo, restClient, i18nService, encryptService, keyService, stateProvider), policyService);
    const fastmail = new create_legacy_username_generation_service_DefaultGeneratorService(new create_legacy_username_generation_service_ForwarderGeneratorStrategy(Integrations.Fastmail, restClient, i18nService, encryptService, keyService, stateProvider), policyService);
    const firefoxRelay = new create_legacy_username_generation_service_DefaultGeneratorService(new create_legacy_username_generation_service_ForwarderGeneratorStrategy(Integrations.FirefoxRelay, restClient, i18nService, encryptService, keyService, stateProvider), policyService);
    const forwardEmail = new create_legacy_username_generation_service_DefaultGeneratorService(new create_legacy_username_generation_service_ForwarderGeneratorStrategy(Integrations.ForwardEmail, restClient, i18nService, encryptService, keyService, stateProvider), policyService);
    const simpleLogin = new create_legacy_username_generation_service_DefaultGeneratorService(new create_legacy_username_generation_service_ForwarderGeneratorStrategy(Integrations.SimpleLogin, restClient, i18nService, encryptService, keyService, stateProvider), policyService);
    const navigation = new DefaultGeneratorNavigationService(stateProvider, policyService);
    return new LegacyUsernameGenerationService(accountService, navigation, catchall, effUsername, subaddress, addyIo, duckDuckGo, fastmail, firefoxRelay, forwardEmail, simpleLogin);
}

;// ../../libs/tools/generator/extensions/legacy/src/index.ts







;// ../../libs/importer/src/metadata/data.ts
/** Mechanisms that load data into the importer. */
const Loader = Object.freeze({
    /** Data loaded from a file provided by the user/ */
    file: "file",
    /** Data loaded directly from the chromium browser's data store */
    chromium: "chromium",
    /** Data provided through an importer ipc channel (e.g. Bitwarden bridge) */
    ipc: "ipc",
    /** Data provided through direct file download (e.g. a LastPass export) */
    download: "download",
});
/** Re-branded products often leave their exporters unaltered; when that occurs,
 *  `Instructions` lets us group them together.
 *
 *  @remarks Instructions values must be mutually exclusive from Loader's values.
 */
const Instructions = Object.freeze({
    /** the instructions are unique to the import type */
    unique: "unique",
    /** shared chromium instructions */
    chromium: "chromium",
});

;// ../../libs/importer/src/metadata/availability.ts



/** Describes which loaders are supported on each client */
const LoaderAvailability = deepFreeze({
    [Loader.chromium]: [src_ClientType.Desktop],
    [Loader.download]: [src_ClientType.Browser],
    [Loader.file]: [src_ClientType.Browser, src_ClientType.Desktop, src_ClientType.Web, src_ClientType.Cli],
    // FIXME: enable IPC importer on `ClientType.Desktop` once it's ready
    [Loader.ipc]: [],
});

;// ../../libs/importer/src/metadata/importers.ts


/** List of all supported importers and their default capabilities
 * Note: the loaders listed here are the ones that are supported in all clients.
 * Specific clients may have additional loaders available based on platform capabilities.
 */
const importers = [
    { id: "bitwardenjson", loaders: [Loader.file], instructions: Instructions.unique },
    // chromecsv import depends upon operating system, so ironically it doesn't support chromium
    { id: "chromecsv", loaders: [Loader.file], instructions: Instructions.chromium },
    { id: "operacsv", loaders: [Loader.file], instructions: Instructions.chromium },
    {
        id: "vivaldicsv",
        loaders: [Loader.file],
        instructions: Instructions.chromium,
    },
    { id: "bravecsv", loaders: [Loader.file], instructions: Instructions.chromium },
    { id: "edgecsv", loaders: [Loader.file], instructions: Instructions.chromium },
    // FIXME: add other formats and remove `Partial` from export
];
/** Describes which loaders are available for each import type */
const Importers = deepFreeze(Object.fromEntries(importers.map((i) => [i.id, i])));

;// ../../libs/importer/src/metadata/index.ts





;// ../../libs/importer/src/services/import-api.service.ts
var import_api_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
class ImportApiService {
    constructor(apiService) {
        this.apiService = apiService;
    }
    postImportCiphers(request) {
        return import_api_service_awaiter(this, void 0, void 0, function* () {
            return yield this.apiService.send("POST", "/ciphers/import", request, true, false);
        });
    }
    postImportOrganizationCiphers(organizationId, request) {
        return import_api_service_awaiter(this, void 0, void 0, function* () {
            return yield this.apiService.send("POST", "/ciphers/import-organization?organizationId=" + organizationId, request, true, false);
        });
    }
}

;// ../../libs/common/src/models/request/import-ciphers.request.ts
class ImportCiphersRequest {
    constructor() {
        this.ciphers = [];
        this.folders = [];
        this.folderRelationships = [];
    }
}

;// ../../libs/common/src/models/request/import-organization-ciphers.request.ts
class ImportOrganizationCiphersRequest {
    constructor() {
        this.ciphers = [];
        this.collections = [];
        this.collectionRelationships = [];
    }
}

;// ../../libs/common/src/models/request/kvp.request.ts
class KvpRequest {
    constructor(key, value) {
        this.key = key;
        this.value = value;
    }
}

;// ../../libs/common/src/vault/models/request/folder-with-optional-id.request.ts

class FolderWithOptionalIdRequest extends FolderRequest {
    constructor(folder) {
        super(folder);
        this.id = folder.id || undefined;
    }
}

;// ../../libs/importer/src/models/import-result.ts
class ImportResult {
    constructor() {
        this.success = false;
        this.ciphers = [];
        this.folders = [];
        this.folderRelationships = [];
        this.collections = [];
        this.collectionRelationships = [];
    }
}

;// ../../libs/common/src/platform/services/console-log.service.ts


;// ../../libs/importer/src/importers/base-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore












class BaseImporter {
    constructor() {
        this.organizationId = null;
        // FIXME: This should be replaced by injecting the log service.
        this.logService = new console_log_service_ConsoleLogService(false);
        this.newLineRegex = /(?:\r\n|\r|\n)/;
        this.passwordFieldNames = [
            "password",
            "pass word",
            "passphrase",
            "pass phrase",
            "pass",
            "code",
            "code word",
            "codeword",
            "secret",
            "secret word",
            "personpwd",
            "key",
            "keyword",
            "key word",
            "keyphrase",
            "key phrase",
            "form_pw",
            "wppassword",
            "pin",
            "pwd",
            "pw",
            "pword",
            "passwd",
            "p",
            "serial",
            "serial#",
            "license key",
            "reg #",
            // Non-English names
            "passwort",
        ];
        this.usernameFieldNames = [
            "user",
            "name",
            "user name",
            "username",
            "login name",
            "email",
            "e-mail",
            "id",
            "userid",
            "user id",
            "login",
            "form_loginname",
            "wpname",
            "mail",
            "loginid",
            "login id",
            "log",
            "personlogin",
            "first name",
            "last name",
            "card#",
            "account #",
            "member",
            "member #",
            // Non-English names
            "nom",
            "benutzername",
        ];
        this.notesFieldNames = [
            "note",
            "notes",
            "comment",
            "comments",
            "memo",
            "description",
            "free form",
            "freeform",
            "free text",
            "freetext",
            "free",
            // Non-English names
            "kommentar",
        ];
        this.uriFieldNames = [
            "url",
            "hyper link",
            "hyperlink",
            "link",
            "host",
            "hostname",
            "host name",
            "server",
            "address",
            "hyper ref",
            "href",
            "web",
            "website",
            "web site",
            "site",
            "web-site",
            "uri",
            // Non-English names
            "ort",
            "adresse",
        ];
        this.parseCsvOptions = {
            encoding: "UTF-8",
            skipEmptyLines: false,
        };
    }
    get organization() {
        return this.organizationId != null;
    }
    parseXml(data) {
        // Ensure there are no external entity elements in the XML to prevent against XXE attacks.
        if (!this.validateNoExternalEntities(data)) {
            return null;
        }
        const parser = new DOMParser();
        const doc = parser.parseFromString(data, "application/xml");
        return doc != null && doc.querySelector("parsererror") == null ? doc : null;
    }
    parseCsv(data, header, options = {}) {
        const parseOptions = Object.assign({ header: header }, this.parseCsvOptions, options);
        data = this.splitNewLine(data).join("\n").trim();
        const result = external_papaparse_namespaceObject.parse(data, parseOptions);
        if (result.errors != null && result.errors.length > 0) {
            result.errors.forEach((e) => {
                if (e.row != null) {
                    this.logService.warning("Error parsing row " + e.row + ": " + e.message);
                }
            });
        }
        return result.data && result.data.length > 0 ? result.data : null;
    }
    parseSingleRowCsv(rowData) {
        if (this.isNullOrWhitespace(rowData)) {
            return null;
        }
        const parsedRow = this.parseCsv(rowData, false);
        if (parsedRow != null && parsedRow.length > 0 && parsedRow[0].length > 0) {
            return parsedRow[0];
        }
        return null;
    }
    makeUriArray(uri) {
        if (uri == null) {
            return null;
        }
        if (typeof uri === "string") {
            const loginUri = new LoginUriView();
            loginUri.uri = this.fixUri(uri);
            if (this.isNullOrWhitespace(loginUri.uri)) {
                return null;
            }
            return [loginUri];
        }
        if (uri.length > 0) {
            const returnArr = [];
            uri.forEach((u) => {
                const loginUri = new LoginUriView();
                loginUri.uri = this.fixUri(u);
                if (this.isNullOrWhitespace(loginUri.uri)) {
                    return;
                }
                returnArr.push(loginUri);
            });
            return returnArr.length === 0 ? null : returnArr;
        }
        return null;
    }
    fixUri(uri) {
        if (uri == null) {
            return null;
        }
        uri = uri.trim();
        if (uri.indexOf("://") === -1 && uri.indexOf(".") >= 0) {
            uri = "http://" + uri;
        }
        if (uri.length > 1000) {
            return uri.substring(0, 1000);
        }
        return uri;
    }
    nameFromUrl(url) {
        const hostname = utils_Utils.getHostname(url);
        if (this.isNullOrWhitespace(hostname)) {
            return null;
        }
        return hostname.startsWith("www.") ? hostname.replace("www.", "") : hostname;
    }
    isNullOrWhitespace(str) {
        return utils_Utils.isNullOrWhitespace(str);
    }
    getValueOrDefault(str, defaultValue = null) {
        if (this.isNullOrWhitespace(str)) {
            return defaultValue;
        }
        return str;
    }
    splitNewLine(str) {
        return str.split(this.newLineRegex);
    }
    setCardExpiration(cipher, expiration) {
        if (this.isNullOrWhitespace(expiration)) {
            return false;
        }
        expiration = expiration.replace(/\s/g, "");
        const monthRegex = "0?(?<month>[1-9]|1[0-2])";
        const yearRegex = "(?<year>(?:[1-2][0-9])?[0-9]{2})";
        const expiryRegex = new RegExp(`^${monthRegex}/${yearRegex}$`);
        const expiryMatch = expiration.match(expiryRegex);
        if (!expiryMatch) {
            return false;
        }
        cipher.card.expMonth = expiryMatch.groups.month;
        const year = expiryMatch.groups.year;
        cipher.card.expYear = normalizeExpiryYearFormat(year);
        return true;
    }
    moveFoldersToCollections(result) {
        result.folderRelationships.forEach((r) => result.collectionRelationships.push(r));
        result.collections = result.folders.map((f) => {
            const collection = new CollectionView({
                name: f.name,
                organizationId: this.organizationId,
                id: f.id && f.id !== "" ? f.id : null,
            });
            return collection;
        });
        result.folderRelationships = [];
        result.folders = [];
    }
    querySelectorDirectChild(parentEl, query) {
        const els = this.querySelectorAllDirectChild(parentEl, query);
        return els.length === 0 ? null : els[0];
    }
    querySelectorAllDirectChild(parentEl, query) {
        return Array.from(parentEl.querySelectorAll(query)).filter((el) => el.parentNode === parentEl);
    }
    initLoginCipher() {
        const cipher = new CipherView();
        cipher.favorite = false;
        cipher.notes = "";
        cipher.fields = [];
        cipher.login = new LoginView();
        cipher.type = CipherType.Login;
        return cipher;
    }
    cleanupCipher(cipher) {
        if (cipher == null) {
            return;
        }
        if (cipher.type !== CipherType.Login) {
            cipher.login = null;
        }
        if (this.isNullOrWhitespace(cipher.name)) {
            cipher.name = "--";
        }
        if (this.isNullOrWhitespace(cipher.notes)) {
            cipher.notes = null;
        }
    }
    processKvp(cipher, key, value, type = FieldType.Text) {
        if (this.isNullOrWhitespace(value)) {
            return;
        }
        if (this.isNullOrWhitespace(key)) {
            key = "";
        }
        if (value.length > 200 || value.trim().search(this.newLineRegex) > -1) {
            if (cipher.notes == null) {
                cipher.notes = "";
            }
            cipher.notes += key + ": " + this.splitNewLine(value).join("\n") + "\n";
        }
        else {
            if (cipher.fields == null) {
                cipher.fields = [];
            }
            const field = new FieldView();
            field.type = type;
            field.name = key;
            field.value = value;
            cipher.fields.push(field);
        }
    }
    processFolder(result, folderName, addRelationship = true) {
        if (this.isNullOrWhitespace(folderName)) {
            return;
        }
        let folderIndex = result.folders.length;
        // Replace backslashes with forward slashes, ensuring we create sub-folders
        folderName = folderName.replace(/\\/g, "/");
        let addFolder = true;
        for (let i = 0; i < result.folders.length; i++) {
            if (result.folders[i].name === folderName) {
                addFolder = false;
                folderIndex = i;
                break;
            }
        }
        if (addFolder) {
            const f = new FolderView();
            f.name = folderName;
            result.folders.push(f);
        }
        //Some folders can have sub-folders but no ciphers directly, we should not add to the folderRelationships array
        if (addRelationship) {
            result.folderRelationships.push([result.ciphers.length, folderIndex]);
        }
        // if the folder name is a/b/c/d, we need to create a/b/c and a/b and a
        const parts = folderName.split("/");
        for (let i = parts.length - 1; i > 0; i--) {
            const parentName = parts.slice(0, i).join("/");
            if (result.folders.find((c) => c.name === parentName) == null) {
                const folder = new FolderView();
                folder.name = parentName;
                result.folders.push(folder);
            }
        }
    }
    convertToNoteIfNeeded(cipher) {
        if (cipher.type === CipherType.Login &&
            this.isNullOrWhitespace(cipher.login.username) &&
            this.isNullOrWhitespace(cipher.login.password) &&
            (cipher.login.uris == null || cipher.login.uris.length === 0)) {
            cipher.type = CipherType.SecureNote;
            cipher.secureNote = new SecureNoteView();
            cipher.secureNote.type = SecureNoteType.Generic;
        }
    }
    processFullName(cipher, fullName) {
        if (this.isNullOrWhitespace(fullName)) {
            return;
        }
        const nameParts = fullName.split(" ");
        if (nameParts.length > 0) {
            cipher.identity.firstName = this.getValueOrDefault(nameParts[0]);
        }
        if (nameParts.length === 2) {
            cipher.identity.lastName = this.getValueOrDefault(nameParts[1]);
        }
        else if (nameParts.length >= 3) {
            cipher.identity.middleName = this.getValueOrDefault(nameParts[1]);
            cipher.identity.lastName = nameParts.slice(2, nameParts.length).join(" ");
        }
    }
    validateNoExternalEntities(data) {
        const regex = new RegExp("<!ENTITY", "i");
        const hasExternalEntities = regex.test(data);
        return !hasExternalEntities;
    }
}

;// ../../libs/importer/src/importers/arc-csv-importer.ts


class ArcCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            var _a;
            const cipher = this.initLoginCipher();
            const url = this.getValueOrDefault(value.url);
            cipher.name = this.getValueOrDefault((_a = this.nameFromUrl(url)) !== null && _a !== void 0 ? _a : "", "--");
            cipher.login.username = this.getValueOrDefault(value.username);
            cipher.login.password = this.getValueOrDefault(value.password);
            cipher.login.uris = this.makeUriArray(value.url);
            cipher.notes = this.getValueOrDefault(value.note);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/ascendo-csv-importer.ts


class AscendoCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, false);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            if (value.length < 2) {
                return;
            }
            const cipher = this.initLoginCipher();
            cipher.notes = this.getValueOrDefault(value[value.length - 1]);
            cipher.name = this.getValueOrDefault(value[0], "--");
            if (value.length > 2 && value.length % 2 === 0) {
                for (let i = 0; i < value.length - 2; i += 2) {
                    const val = value[i + 2];
                    const field = value[i + 1];
                    if (this.isNullOrWhitespace(val) || this.isNullOrWhitespace(field)) {
                        continue;
                    }
                    const fieldLower = field.toLowerCase();
                    if (cipher.login.password == null && this.passwordFieldNames.indexOf(fieldLower) > -1) {
                        cipher.login.password = this.getValueOrDefault(val);
                    }
                    else if (cipher.login.username == null &&
                        this.usernameFieldNames.indexOf(fieldLower) > -1) {
                        cipher.login.username = this.getValueOrDefault(val);
                    }
                    else if ((cipher.login.uris == null || cipher.login.uris.length === 0) &&
                        this.uriFieldNames.indexOf(fieldLower) > -1) {
                        cipher.login.uris = this.makeUriArray(val);
                    }
                    else {
                        this.processKvp(cipher, field, val);
                    }
                }
            }
            this.convertToNoteIfNeeded(cipher);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/avast/avast-csv-importer.ts


class AvastCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(value.name);
            cipher.login.uris = this.makeUriArray(value.web);
            cipher.login.password = this.getValueOrDefault(value.password);
            cipher.login.username = this.getValueOrDefault(value.login);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/avast/avast-json-importer.ts




class AvastJsonImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = JSON.parse(data);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        if (results.logins != null) {
            results.logins.forEach((value) => {
                const cipher = this.initLoginCipher();
                cipher.name = this.getValueOrDefault(value.custName);
                cipher.notes = this.getValueOrDefault(value.note);
                cipher.login.uris = this.makeUriArray(value.url);
                cipher.login.password = this.getValueOrDefault(value.pwd);
                cipher.login.username = this.getValueOrDefault(value.loginName);
                this.cleanupCipher(cipher);
                result.ciphers.push(cipher);
            });
        }
        if (results.notes != null) {
            results.notes.forEach((value) => {
                const cipher = this.initLoginCipher();
                cipher.type = CipherType.SecureNote;
                cipher.secureNote.type = SecureNoteType.Generic;
                cipher.name = this.getValueOrDefault(value.label);
                cipher.notes = this.getValueOrDefault(value.text);
                this.cleanupCipher(cipher);
                result.ciphers.push(cipher);
            });
        }
        if (results.cards != null) {
            results.cards.forEach((value) => {
                const cipher = this.initLoginCipher();
                cipher.type = CipherType.Card;
                cipher.name = this.getValueOrDefault(value.custName);
                cipher.notes = this.getValueOrDefault(value.note);
                cipher.card.cardholderName = this.getValueOrDefault(value.holderName);
                cipher.card.number = this.getValueOrDefault(value.cardNumber);
                cipher.card.code = this.getValueOrDefault(value.cvv);
                cipher.card.brand = CardView.getCardBrandByPatterns(cipher.card.number);
                if (value.expirationDate != null) {
                    if (value.expirationDate.month != null) {
                        cipher.card.expMonth = value.expirationDate.month + "";
                    }
                    if (value.expirationDate.year != null) {
                        cipher.card.expYear = value.expirationDate.year + "";
                    }
                }
                this.cleanupCipher(cipher);
                result.ciphers.push(cipher);
            });
        }
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/avast/index.ts



;// ../../libs/importer/src/importers/avira-csv-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


class AviraCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(value.name, this.getValueOrDefault(this.nameFromUrl(value.website), "--"));
            cipher.login.uris = this.makeUriArray(value.website);
            cipher.login.password = this.getValueOrDefault(value.password);
            if (this.isNullOrWhitespace(value.username) &&
                !this.isNullOrWhitespace(value.secondary_username)) {
                cipher.login.username = value.secondary_username;
            }
            else {
                cipher.login.username = this.getValueOrDefault(value.username);
                cipher.notes = this.getValueOrDefault(value.secondary_username);
            }
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/blackberry-csv-importer.ts


class BlackBerryCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            if (value.grouping === "list") {
                return;
            }
            const cipher = this.initLoginCipher();
            cipher.favorite = value.fav === "1";
            cipher.name = this.getValueOrDefault(value.name);
            cipher.notes = this.getValueOrDefault(value.extra);
            if (value.grouping !== "note") {
                cipher.login.uris = this.makeUriArray(value.url);
                cipher.login.password = this.getValueOrDefault(value.password);
                cipher.login.username = this.getValueOrDefault(value.username);
            }
            this.convertToNoteIfNeeded(cipher);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/chrome-csv-importer.ts


class ChromeCsvImporter extends BaseImporter {
    constructor() {
        super(...arguments);
        this.androidPatternRegex = new RegExp("^android:\\/\\/.*(?<=@)(.*)(?=\\/)");
    }
    normalizeAndroidUrl(url) {
        const match = url === null || url === void 0 ? void 0 : url.match(this.androidPatternRegex);
        return match ? `androidapp://${match[1]}` : url;
    }
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            const cipher = this.initLoginCipher();
            const normalizedUri = this.normalizeAndroidUrl(value.url);
            let name = value.name;
            if (!name && this.androidPatternRegex.test(value.url)) {
                name = value.url.match(this.androidPatternRegex)[1];
            }
            cipher.name = this.getValueOrDefault(name, "--");
            cipher.login.username = this.getValueOrDefault(value.username);
            cipher.login.password = this.getValueOrDefault(value.password);
            cipher.login.uris = this.makeUriArray(normalizedUri);
            cipher.notes = this.getValueOrDefault(value.note);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/bitwarden/bitwarden-csv-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore








class BitwardenCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            if (this.organization && !this.isNullOrWhitespace(value.collections)) {
                const collections = value.collections.split(",");
                collections.forEach((col) => {
                    // here processFolder is used to create collections
                    // In an Organization folders are converted to collections
                    // see line just before this function terminates
                    // where all folders are turned to collections
                    this.processFolder(result, col);
                });
            }
            else if (!this.organization) {
                this.processFolder(result, value.folder);
            }
            const cipher = new CipherView();
            cipher.favorite =
                !this.organization && this.getValueOrDefault(value.favorite, "0") !== "0" ? true : false;
            cipher.type = CipherType.Login;
            cipher.notes = this.getValueOrDefault(value.notes);
            cipher.name = this.getValueOrDefault(value.name, "--");
            try {
                cipher.reprompt = parseInt(this.getValueOrDefault(value.reprompt, CipherRepromptType.None.toString()), 10);
            }
            catch (e) {
                // eslint-disable-next-line
                console.error("Unable to parse reprompt value", e);
                cipher.reprompt = CipherRepromptType.None;
            }
            if (!this.isNullOrWhitespace(value.archivedDate)) {
                try {
                    cipher.archivedDate = new Date(value.archivedDate);
                }
                catch (e) {
                    // eslint-disable-next-line
                    console.error("Unable to parse archivedDate value", e);
                }
            }
            if (!this.isNullOrWhitespace(value.fields)) {
                const fields = this.splitNewLine(value.fields);
                for (let i = 0; i < fields.length; i++) {
                    if (this.isNullOrWhitespace(fields[i])) {
                        continue;
                    }
                    const delimPosition = fields[i].lastIndexOf(": ");
                    if (delimPosition === -1) {
                        continue;
                    }
                    if (cipher.fields == null) {
                        cipher.fields = [];
                    }
                    const field = new FieldView();
                    field.name = fields[i].substr(0, delimPosition);
                    field.value = null;
                    field.type = FieldType.Text;
                    if (fields[i].length > delimPosition + 2) {
                        field.value = fields[i].substr(delimPosition + 2);
                    }
                    cipher.fields.push(field);
                }
            }
            const valueType = value.type != null ? value.type.toLowerCase() : null;
            switch (valueType) {
                case "note":
                    cipher.type = CipherType.SecureNote;
                    cipher.secureNote = new SecureNoteView();
                    cipher.secureNote.type = SecureNoteType.Generic;
                    break;
                default: {
                    cipher.type = CipherType.Login;
                    cipher.login = new LoginView();
                    cipher.login.totp = this.getValueOrDefault(value.login_totp || value.totp);
                    cipher.login.username = this.getValueOrDefault(value.login_username || value.username);
                    cipher.login.password = this.getValueOrDefault(value.login_password || value.password);
                    const uris = this.parseSingleRowCsv(value.login_uri || value.uri);
                    cipher.login.uris = this.makeUriArray(uris);
                    break;
                }
            }
            result.ciphers.push(cipher);
        });
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/bitwarden/bitwarden-json-importer.ts
var bitwarden_json_importer_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore




class BitwardenJsonImporter extends BaseImporter {
    constructor() {
        super();
    }
    parse(data) {
        return bitwarden_json_importer_awaiter(this, void 0, void 0, function* () {
            const results = JSON.parse(data);
            if (results == null || results.items == null) {
                const result = new ImportResult();
                result.success = false;
                return result;
            }
            if (!isUnencrypted(results)) {
                throw new Error("Data is encrypted. Use BitwardenEncryptedJsonImporter instead.");
            }
            return yield this.parseDecrypted(results);
        });
    }
    parseDecrypted(results) {
        return bitwarden_json_importer_awaiter(this, void 0, void 0, function* () {
            const importResult = new ImportResult();
            const groupingsMap = isOrgUnEncrypted(results)
                ? yield this.parseCollections(results, importResult)
                : yield this.parseFolders(results, importResult);
            results.items.forEach((c) => {
                const cipher = CipherWithIdExport.toView(c);
                // reset ids in case they were set for some reason
                cipher.id = null;
                cipher.organizationId = null;
                cipher.collectionIds = null;
                // make sure password history is limited
                if (cipher.passwordHistory != null && cipher.passwordHistory.length > 5) {
                    cipher.passwordHistory = cipher.passwordHistory.slice(0, 5);
                }
                if (!this.organization && c.folderId != null && groupingsMap.has(c.folderId)) {
                    importResult.folderRelationships.push([
                        importResult.ciphers.length,
                        groupingsMap.get(c.folderId),
                    ]);
                }
                else if (this.organization && c.collectionIds != null) {
                    c.collectionIds.forEach((cId) => {
                        if (groupingsMap.has(cId)) {
                            importResult.collectionRelationships.push([
                                importResult.ciphers.length,
                                groupingsMap.get(cId),
                            ]);
                        }
                    });
                }
                this.cleanupCipher(cipher);
                importResult.ciphers.push(cipher);
            });
            importResult.success = true;
            return importResult;
        });
    }
    parseFolders(data, importResult) {
        return bitwarden_json_importer_awaiter(this, void 0, void 0, function* () {
            const groupingsMap = new Map();
            if (data.folders == null) {
                return groupingsMap;
            }
            for (const f of data.folders) {
                const folderView = FolderWithIdExport.toView(f);
                if (folderView != null) {
                    groupingsMap.set(f.id, importResult.folders.length);
                    importResult.folders.push(folderView);
                }
            }
            return groupingsMap;
        });
    }
    parseCollections(data, importResult) {
        return bitwarden_json_importer_awaiter(this, void 0, void 0, function* () {
            const groupingsMap = new Map();
            if (data.collections == null) {
                return groupingsMap;
            }
            for (const c of data.collections) {
                const collectionView = CollectionWithIdExport.toView(c);
                collectionView.organizationId = null;
                if (collectionView != null) {
                    groupingsMap.set(c.id, importResult.collections.length);
                    importResult.collections.push(collectionView);
                }
            }
            return groupingsMap;
        });
    }
}

;// ../../libs/importer/src/importers/bitwarden/bitwarden-encrypted-json-importer.ts
var bitwarden_encrypted_json_importer_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore







class BitwardenEncryptedJsonImporter extends BitwardenJsonImporter {
    constructor(keyService, encryptService, i18nService, cipherService, accountService) {
        super();
        this.keyService = keyService;
        this.encryptService = encryptService;
        this.i18nService = i18nService;
        this.cipherService = cipherService;
        this.accountService = accountService;
    }
    parse(data) {
        const _super = Object.create(null, {
            parse: { get: () => super.parse }
        });
        return bitwarden_encrypted_json_importer_awaiter(this, void 0, void 0, function* () {
            const results = JSON.parse(data);
            if (isPasswordProtected(results)) {
                throw new Error("Data is password-protected. Use BitwardenPasswordProtectedImporter instead.");
            }
            if (results == null || results.items == null) {
                const result = new ImportResult();
                result.success = false;
                return result;
            }
            if (isUnencrypted(results)) {
                return _super.parse.call(this, data);
            }
            return yield this.parseEncrypted(results);
        });
    }
    parseEncrypted(data) {
        return bitwarden_encrypted_json_importer_awaiter(this, void 0, void 0, function* () {
            const result = new ImportResult();
            const account = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$);
            if (this.isNullOrWhitespace(data.encKeyValidation_DO_NOT_EDIT)) {
                result.success = false;
                result.errorMessage = this.i18nService.t("importEncKeyError");
                return result;
            }
            const orgKeys = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.orgKeys$(account.id));
            let keyForDecryption = orgKeys === null || orgKeys === void 0 ? void 0 : orgKeys[this.organizationId];
            if (!keyForDecryption) {
                keyForDecryption = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.userKey$(account.id));
            }
            if (!keyForDecryption) {
                result.success = false;
                result.errorMessage = this.i18nService.t("importEncKeyError");
                return result;
            }
            const encKeyValidation = new enc_string_EncString(data.encKeyValidation_DO_NOT_EDIT);
            try {
                yield this.encryptService.decryptString(encKeyValidation, keyForDecryption);
            }
            catch (_a) {
                result.success = false;
                result.errorMessage = this.i18nService.t("importEncKeyError");
                return result;
            }
            let groupingsMap = null;
            if (isOrgEncrypted(data)) {
                groupingsMap = yield this.parseEncryptedCollections(account.id, data, result);
            }
            else {
                groupingsMap = yield this.parseEncryptedFolders(account.id, data, result);
            }
            for (const c of data.items) {
                const cipher = CipherWithIdExport.toDomain(c);
                // reset ids in case they were set for some reason
                cipher.id = null;
                cipher.organizationId = this.organizationId;
                cipher.collectionIds = null;
                // make sure password history is limited
                if (cipher.passwordHistory != null && cipher.passwordHistory.length > 5) {
                    cipher.passwordHistory = cipher.passwordHistory.slice(0, 5);
                }
                if (!this.organization && c.folderId != null && groupingsMap.has(c.folderId)) {
                    result.folderRelationships.push([result.ciphers.length, groupingsMap.get(c.folderId)]);
                }
                else if (this.organization && c.collectionIds != null) {
                    c.collectionIds.forEach((cId) => {
                        if (groupingsMap.has(cId)) {
                            result.collectionRelationships.push([result.ciphers.length, groupingsMap.get(cId)]);
                        }
                    });
                }
                const view = yield this.cipherService.decrypt(cipher, account.id);
                this.cleanupCipher(view);
                result.ciphers.push(view);
            }
            result.success = true;
            return result;
        });
    }
    parseEncryptedFolders(userId, data, importResult) {
        return bitwarden_encrypted_json_importer_awaiter(this, void 0, void 0, function* () {
            const groupingsMap = new Map();
            if (data.folders == null) {
                return groupingsMap;
            }
            const userKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.userKey$(userId));
            for (const f of data.folders) {
                let folderView;
                const folder = FolderWithIdExport.toDomain(f);
                if (folder != null) {
                    folderView = yield folder.decrypt(userKey);
                }
                if (folderView != null) {
                    groupingsMap.set(f.id, importResult.folders.length);
                    importResult.folders.push(folderView);
                }
            }
            return groupingsMap;
        });
    }
    parseEncryptedCollections(userId, data, importResult) {
        return bitwarden_encrypted_json_importer_awaiter(this, void 0, void 0, function* () {
            const groupingsMap = new Map();
            if (data.collections == null) {
                return groupingsMap;
            }
            const orgKeys = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.orgKeys$(userId).pipe((0,external_rxjs_namespaceObject.filter)((orgKeys) => orgKeys != null)));
            for (const c of data.collections) {
                const collection = CollectionWithIdExport.toDomain(c, new Collection({
                    id: c.id,
                    name: new enc_string_EncString(c.name),
                    organizationId: this.organizationId,
                }));
                const orgKey = orgKeys[c.organizationId];
                const collectionView = yield collection.decrypt(orgKey, this.encryptService);
                if (collectionView != null) {
                    groupingsMap.set(c.id, importResult.collections.length);
                    importResult.collections.push(collectionView);
                }
            }
            return groupingsMap;
        });
    }
}

;// ../../libs/importer/src/importers/bitwarden/bitwarden-password-protected-importer.ts
var bitwarden_password_protected_importer_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};





class BitwardenPasswordProtectedImporter extends BitwardenEncryptedJsonImporter {
    constructor(keyService, encryptService, i18nService, cipherService, keyGenerationService, accountService, promptForPassword_callback) {
        super(keyService, encryptService, i18nService, cipherService, accountService);
        this.keyGenerationService = keyGenerationService;
        this.promptForPassword_callback = promptForPassword_callback;
    }
    parse(data) {
        const _super = Object.create(null, {
            parse: { get: () => super.parse }
        });
        return bitwarden_password_protected_importer_awaiter(this, void 0, void 0, function* () {
            const result = new ImportResult();
            const parsedData = JSON.parse(data);
            if (!parsedData) {
                result.success = false;
                return result;
            }
            if (!isPasswordProtected(parsedData)) {
                return yield _super.parse.call(this, data);
            }
            if (this.cannotParseFile(parsedData)) {
                result.success = false;
                return result;
            }
            // File is password-protected
            const password = yield this.promptForPassword_callback();
            if (!(yield this.checkPassword(parsedData, password))) {
                result.success = false;
                result.errorMessage = this.i18nService.t("invalidFilePassword");
                return result;
            }
            const encData = new enc_string_EncString(parsedData.data);
            const clearTextData = yield this.encryptService.decryptString(encData, this.key);
            return yield _super.parse.call(this, clearTextData);
        });
    }
    checkPassword(jdoc, password) {
        return bitwarden_password_protected_importer_awaiter(this, void 0, void 0, function* () {
            if (this.isNullOrWhitespace(password)) {
                return false;
            }
            const kdfConfig = jdoc.kdfType === kdf_type_enum_KdfType.PBKDF2_SHA256
                ? new PBKDF2KdfConfig(jdoc.kdfIterations)
                : new Argon2KdfConfig(jdoc.kdfIterations, jdoc.kdfMemory, jdoc.kdfParallelism);
            this.key = yield this.keyGenerationService.deriveVaultExportKey(password, jdoc.salt, kdfConfig);
            const encKeyValidation = new enc_string_EncString(jdoc.encKeyValidation_DO_NOT_EDIT);
            try {
                yield this.encryptService.decryptString(encKeyValidation, this.key);
                return true;
            }
            catch (_a) {
                return false;
            }
        });
    }
    cannotParseFile(jdoc) {
        return (!jdoc ||
            !jdoc.encrypted ||
            !jdoc.passwordProtected ||
            !jdoc.salt ||
            !jdoc.kdfIterations ||
            typeof jdoc.kdfIterations !== "number" ||
            jdoc.kdfType == null ||
            kdf_type_enum_KdfType[jdoc.kdfType] == null ||
            !jdoc.encKeyValidation_DO_NOT_EDIT ||
            !jdoc.data);
    }
}

;// ../../libs/importer/src/importers/bitwarden/index.ts




;// ../../libs/importer/src/importers/blur-csv-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


class BlurCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            if (value.label === "null") {
                value.label = null;
            }
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(value.label, this.getValueOrDefault(this.nameFromUrl(value.domain), "--"));
            cipher.login.uris = this.makeUriArray(value.domain);
            cipher.login.password = this.getValueOrDefault(value.password);
            if (this.isNullOrWhitespace(value.email) && !this.isNullOrWhitespace(value.username)) {
                cipher.login.username = value.username;
            }
            else {
                cipher.login.username = this.getValueOrDefault(value.email);
                cipher.notes = this.getValueOrDefault(value.username);
            }
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/buttercup-csv-importer.ts


const OfficialProps = [
    "!group_id",
    "!group_name",
    "!type",
    "title",
    "username",
    "password",
    "URL",
    "url",
    "note",
    "id",
];
class ButtercupCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            this.processFolder(result, this.getValueOrDefault(value["!group_name"]));
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(value.title, "--");
            cipher.login.username = this.getValueOrDefault(value.username);
            cipher.login.password = this.getValueOrDefault(value.password);
            // Handle URL field (case-insensitive)
            const urlValue = value.URL || value.url || value.Url;
            cipher.login.uris = this.makeUriArray(urlValue);
            // Handle note field (case-insensitive)
            const noteValue = value.note || value.Note || value.notes || value.Notes;
            if (noteValue) {
                cipher.notes = noteValue;
            }
            // Process custom fields, excluding official props (case-insensitive)
            for (const prop in value) {
                // eslint-disable-next-line
                if (value.hasOwnProperty(prop)) {
                    const lowerProp = prop.toLowerCase();
                    const isOfficialProp = OfficialProps.some((p) => p.toLowerCase() === lowerProp);
                    if (!isOfficialProp && value[prop]) {
                        this.processKvp(cipher, prop, value[prop]);
                    }
                }
            }
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/clipperz-html-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


class ClipperzHtmlImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const doc = this.parseXml(data);
        if (doc == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        const textarea = doc.querySelector("textarea");
        if (textarea == null || this.isNullOrWhitespace(textarea.textContent)) {
            result.errorMessage = "Missing textarea.";
            result.success = false;
            return Promise.resolve(result);
        }
        const entries = JSON.parse(textarea.textContent);
        entries.forEach((entry) => {
            const cipher = this.initLoginCipher();
            if (!this.isNullOrWhitespace(entry.label)) {
                cipher.name = entry.label.split(" ")[0];
            }
            if (entry.data != null && !this.isNullOrWhitespace(entry.data.notes)) {
                cipher.notes = entry.data.notes.split("\\n").join("\n");
            }
            if (entry.currentVersion != null && entry.currentVersion.fields != null) {
                for (const property in entry.currentVersion.fields) {
                    // eslint-disable-next-line
                    if (!entry.currentVersion.fields.hasOwnProperty(property)) {
                        continue;
                    }
                    const field = entry.currentVersion.fields[property];
                    const actionType = field.actionType != null ? field.actionType.toLowerCase() : null;
                    switch (actionType) {
                        case "password":
                            cipher.login.password = this.getValueOrDefault(field.value);
                            break;
                        case "email":
                        case "username":
                        case "user":
                        case "name":
                            cipher.login.username = this.getValueOrDefault(field.value);
                            break;
                        case "url":
                            cipher.login.uris = this.makeUriArray(field.value);
                            break;
                        default: {
                            const labelLower = field.label != null ? field.label.toLowerCase() : null;
                            if (cipher.login.password == null &&
                                this.passwordFieldNames.indexOf(labelLower) > -1) {
                                cipher.login.password = this.getValueOrDefault(field.value);
                            }
                            else if (cipher.login.username == null &&
                                this.usernameFieldNames.indexOf(labelLower) > -1) {
                                cipher.login.username = this.getValueOrDefault(field.value);
                            }
                            else if ((cipher.login.uris == null || cipher.login.uris.length === 0) &&
                                this.uriFieldNames.indexOf(labelLower) > -1) {
                                cipher.login.uris = this.makeUriArray(field.value);
                            }
                            else {
                                this.processKvp(cipher, field.label, field.value);
                            }
                            break;
                        }
                    }
                }
            }
            this.convertToNoteIfNeeded(cipher);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/codebook-csv-importer.ts


class CodebookCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            this.processFolder(result, this.getValueOrDefault(value.Category));
            const cipher = this.initLoginCipher();
            cipher.favorite = this.getValueOrDefault(value.Favorite) === "True";
            cipher.name = this.getValueOrDefault(value.Entry, "--");
            cipher.notes = this.getValueOrDefault(value.Note);
            cipher.login.username = this.getValueOrDefault(value.Username, value.Email);
            cipher.login.password = this.getValueOrDefault(value.Password);
            cipher.login.totp = this.getValueOrDefault(value.TOTP);
            cipher.login.uris = this.makeUriArray(value.Website);
            if (!this.isNullOrWhitespace(value.Username)) {
                this.processKvp(cipher, "Email", value.Email);
            }
            this.processKvp(cipher, "Phone", value.Phone);
            this.processKvp(cipher, "PIN", value.PIN);
            this.processKvp(cipher, "Account", value.Account);
            this.processKvp(cipher, "Date", value.Date);
            this.convertToNoteIfNeeded(cipher);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/dashlane/dashlane-csv-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore






const _mappedCredentialsColumns = new Set([
    "title",
    "note",
    "username",
    "password",
    "url",
    "otpSecret",
    "category",
]);
const _mappedPersonalInfoAsIdentityColumns = new Set([
    "type",
    "title",
    "first_name",
    "middle_name",
    "last_name",
    "login",
    "email",
    "phone_number",
    "address",
    "country",
    "state",
    "city",
    "zip",
    // Skip item_name as we already have set a combined name
    "item_name",
]);
const _mappedSecureNoteColumns = new Set(["title", "note"]);
class DashlaneCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        if (results[0].type != null && results[0].title != null) {
            const personalRecords = results;
            // If personalRecords has only one "name" then create an Identity-Cipher
            if (personalRecords.filter((x) => x.type === "name").length === 1) {
                const cipher = this.initLoginCipher();
                cipher.type = CipherType.Identity;
                cipher.identity = new IdentityView();
                results.forEach((row) => {
                    this.parsePersonalInformationRecordAsIdentity(cipher, row);
                });
                this.cleanupCipher(cipher);
                result.ciphers.push(cipher);
                result.success = true;
                return Promise.resolve(result);
            }
        }
        results.forEach((row) => {
            const cipher = this.initLoginCipher();
            const rowKeys = Object.keys(row);
            if (rowKeys[0] === "username") {
                this.processFolder(result, row.category);
                this.parseCredentialsRecord(cipher, row);
            }
            if (rowKeys[0] === "type" && rowKeys[1] === "account_name") {
                this.parsePaymentRecord(cipher, row);
            }
            if (rowKeys[0] === "type" && rowKeys[1] === "number") {
                this.parseIdRecord(cipher, row);
            }
            if (rowKeys[0] === "type" && rowKeys[1] === "title") {
                this.parsePersonalInformationRecord(cipher, row);
            }
            if (rowKeys[0] === "title" && rowKeys[1] === "note") {
                this.parseSecureNoteRecords(cipher, row);
            }
            this.convertToNoteIfNeeded(cipher);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
    parseCredentialsRecord(cipher, row) {
        cipher.type = CipherType.Login;
        cipher.login = new LoginView();
        cipher.name = row.title;
        cipher.notes = row.note;
        cipher.login.username = row.username;
        cipher.login.password = row.password;
        cipher.login.totp = Object.keys(row).includes("otpUrl") ? row.otpUrl : row.otpSecret;
        cipher.login.uris = this.makeUriArray(row.url);
        this.importUnmappedFields(cipher, row, _mappedCredentialsColumns);
    }
    parsePaymentRecord(cipher, row) {
        cipher.type = CipherType.Card;
        cipher.card = new CardView();
        cipher.name = row.account_name;
        let mappedValues = [];
        switch (row.type) {
            case "credit_card":
                cipher.card.cardholderName = row.account_name;
                cipher.card.number = row.cc_number;
                cipher.card.brand = CardView.getCardBrandByPatterns(cipher.card.number);
                cipher.card.code = row.code;
                this.setCardExpiration(cipher, `${row.expiration_month}/${row.expiration_year}`);
                // If you add more mapped fields please extend this
                mappedValues = [
                    "account_name",
                    "account_holder",
                    "cc_number",
                    "code",
                    "expiration_month",
                    "expiration_year",
                ];
                break;
            case "bank":
                cipher.card.cardholderName = row.account_holder;
                cipher.card.number = row.account_number;
                // If you add more mapped fields please extend this
                mappedValues = ["account_name", "account_holder", "account_number"];
                break;
            default:
                break;
        }
        this.importUnmappedFields(cipher, row, new Set(mappedValues));
    }
    parseIdRecord(cipher, row) {
        cipher.type = CipherType.Identity;
        cipher.identity = new IdentityView();
        const mappedValues = ["name", "number"];
        switch (row.type) {
            case "card":
                cipher.name = `${row.name} ${row.type}`;
                this.processFullName(cipher, row.name);
                cipher.identity.licenseNumber = row.number;
                break;
            case "passport":
                cipher.name = `${row.name} ${row.type}`;
                this.processFullName(cipher, row.name);
                cipher.identity.passportNumber = row.number;
                break;
            case "license":
                cipher.name = `${row.name} ${row.type}`;
                this.processFullName(cipher, row.name);
                cipher.identity.licenseNumber = row.number;
                cipher.identity.state = row.state;
                mappedValues.push("state");
                break;
            case "social_security":
                cipher.name = `${row.name} ${row.type}`;
                this.processFullName(cipher, row.name);
                cipher.identity.ssn = row.number;
                break;
            case "tax_number":
                cipher.name = row.type;
                cipher.identity.licenseNumber = row.number;
                break;
            default:
                break;
        }
        // If you add more mapped fields please extend this
        this.importUnmappedFields(cipher, row, new Set(mappedValues));
    }
    parsePersonalInformationRecord(cipher, row) {
        cipher.type = CipherType.SecureNote;
        cipher.secureNote.type = SecureNoteType.Generic;
        if (row.type === "name") {
            cipher.name = `${row.title} ${row.first_name} ${row.middle_name} ${row.last_name}`
                .replace("  ", " ")
                .trim();
        }
        else {
            cipher.name = row.item_name;
        }
        const dataRow = row;
        Object.keys(row).forEach((key) => {
            this.processKvp(cipher, key, dataRow[key]);
        });
    }
    parsePersonalInformationRecordAsIdentity(cipher, row) {
        switch (row.type) {
            case "name":
                this.processFullName(cipher, `${row.first_name} ${row.middle_name} ${row.last_name}`);
                cipher.identity.title = row.title;
                cipher.name = cipher.identity.fullName;
                cipher.identity.username = row.login;
                break;
            case "email":
                cipher.identity.email = row.email;
                break;
            case "number":
                cipher.identity.phone = row.phone_number;
                break;
            case "address":
                cipher.identity.address1 = row.address;
                cipher.identity.city = row.city;
                cipher.identity.postalCode = row.zip;
                cipher.identity.state = row.state;
                cipher.identity.country = row.country;
                break;
            default:
                break;
        }
        this.importUnmappedFields(cipher, row, _mappedPersonalInfoAsIdentityColumns);
    }
    parseSecureNoteRecords(cipher, row) {
        cipher.type = CipherType.SecureNote;
        cipher.secureNote.type = SecureNoteType.Generic;
        cipher.name = row.title;
        cipher.notes = row.note;
        this.importUnmappedFields(cipher, row, _mappedSecureNoteColumns);
    }
    importUnmappedFields(cipher, row, mappedValues) {
        const unmappedFields = Object.keys(row).filter((x) => !mappedValues.has(x));
        unmappedFields.forEach((key) => {
            const item = row;
            this.processKvp(cipher, key, item[key]);
        });
    }
}

;// ../../libs/importer/src/importers/dashlane/dashlane-json-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore







const HandledResults = new Set([
    "ADDRESS",
    "AUTHENTIFIANT",
    "BANKSTATEMENT",
    "IDCARD",
    "IDENTITY",
    "PAYMENTMEANS_CREDITCARD",
    "PAYMENTMEAN_PAYPAL",
    "EMAIL",
]);
class DashlaneJsonImporter extends BaseImporter {
    parse(data) {
        this.result = new ImportResult();
        const results = JSON.parse(data);
        if (results == null || results.length === 0) {
            this.result.success = false;
            return Promise.resolve(this.result);
        }
        if (results.ADDRESS != null) {
            this.processAddress(results.ADDRESS);
        }
        if (results.AUTHENTIFIANT != null) {
            this.processAuth(results.AUTHENTIFIANT);
        }
        if (results.BANKSTATEMENT != null) {
            this.processNote(results.BANKSTATEMENT, "BankAccountName");
        }
        if (results.IDCARD != null) {
            this.processNote(results.IDCARD, "Fullname");
        }
        if (results.PAYMENTMEANS_CREDITCARD != null) {
            this.processCard(results.PAYMENTMEANS_CREDITCARD);
        }
        if (results.IDENTITY != null) {
            this.processIdentity(results.IDENTITY);
        }
        for (const key in results) {
            // eslint-disable-next-line
            if (results.hasOwnProperty(key) && !HandledResults.has(key)) {
                this.processNote(results[key], null, "Generic Note");
            }
        }
        this.result.success = true;
        return Promise.resolve(this.result);
    }
    processAuth(results) {
        results.forEach((credential) => {
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(credential.title);
            cipher.login.username = this.getValueOrDefault(credential.login, this.getValueOrDefault(credential.secondaryLogin));
            if (this.isNullOrWhitespace(cipher.login.username)) {
                cipher.login.username = this.getValueOrDefault(credential.email);
            }
            else if (!this.isNullOrWhitespace(credential.email)) {
                cipher.notes = "Email: " + credential.email + "\n";
            }
            cipher.login.password = this.getValueOrDefault(credential.password);
            cipher.login.uris = this.makeUriArray(credential.domain);
            cipher.notes += this.getValueOrDefault(credential.note, "");
            this.convertToNoteIfNeeded(cipher);
            this.cleanupCipher(cipher);
            this.result.ciphers.push(cipher);
        });
    }
    processIdentity(results) {
        results.forEach((obj) => {
            const cipher = new CipherView();
            cipher.identity = new IdentityView();
            cipher.type = CipherType.Identity;
            cipher.name = this.getValueOrDefault(obj.fullName, "");
            const nameParts = cipher.name.split(" ");
            if (nameParts.length > 0) {
                cipher.identity.firstName = this.getValueOrDefault(nameParts[0]);
            }
            if (nameParts.length === 2) {
                cipher.identity.lastName = this.getValueOrDefault(nameParts[1]);
            }
            else if (nameParts.length === 3) {
                cipher.identity.middleName = this.getValueOrDefault(nameParts[1]);
                cipher.identity.lastName = this.getValueOrDefault(nameParts[2]);
            }
            cipher.identity.username = this.getValueOrDefault(obj.pseudo);
            this.cleanupCipher(cipher);
            this.result.ciphers.push(cipher);
        });
    }
    processAddress(results) {
        results.forEach((obj) => {
            const cipher = new CipherView();
            cipher.identity = new IdentityView();
            cipher.type = CipherType.Identity;
            cipher.name = this.getValueOrDefault(obj.addressName);
            cipher.identity.address1 = this.getValueOrDefault(obj.addressFull);
            cipher.identity.city = this.getValueOrDefault(obj.city);
            cipher.identity.state = this.getValueOrDefault(obj.state);
            cipher.identity.postalCode = this.getValueOrDefault(obj.zipcode);
            cipher.identity.country = this.getValueOrDefault(obj.country);
            if (cipher.identity.country != null) {
                cipher.identity.country = cipher.identity.country.toUpperCase();
            }
            this.cleanupCipher(cipher);
            this.result.ciphers.push(cipher);
        });
    }
    processCard(results) {
        results.forEach((obj) => {
            const cipher = new CipherView();
            cipher.card = new CardView();
            cipher.type = CipherType.Card;
            cipher.name = this.getValueOrDefault(obj.bank);
            cipher.card.number = this.getValueOrDefault(obj.cardNumber);
            cipher.card.brand = CardView.getCardBrandByPatterns(cipher.card.number);
            cipher.card.cardholderName = this.getValueOrDefault(obj.owner);
            if (!this.isNullOrWhitespace(cipher.card.brand)) {
                if (this.isNullOrWhitespace(cipher.name)) {
                    cipher.name = cipher.card.brand;
                }
                else {
                    cipher.name += " - " + cipher.card.brand;
                }
            }
            this.cleanupCipher(cipher);
            this.result.ciphers.push(cipher);
        });
    }
    processNote(results, nameProperty, name = null) {
        results.forEach((obj) => {
            const cipher = new CipherView();
            cipher.secureNote = new SecureNoteView();
            cipher.type = CipherType.SecureNote;
            cipher.secureNote.type = SecureNoteType.Generic;
            if (name != null) {
                cipher.name = name;
            }
            else {
                cipher.name = this.getValueOrDefault(obj[nameProperty]);
            }
            for (const key in obj) {
                // eslint-disable-next-line
                if (obj.hasOwnProperty(key) && key !== nameProperty) {
                    this.processKvp(cipher, key, obj[key].toString());
                }
            }
            this.cleanupCipher(cipher);
            this.result.ciphers.push(cipher);
        });
    }
}

;// ../../libs/importer/src/importers/dashlane/index.ts



;// ../../libs/importer/src/importers/encryptr-csv-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore




class EncryptrCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(value.Label, "--");
            cipher.notes = this.getValueOrDefault(value.Notes);
            const text = this.getValueOrDefault(value.Text);
            if (!this.isNullOrWhitespace(text)) {
                if (this.isNullOrWhitespace(cipher.notes)) {
                    cipher.notes = text;
                }
                else {
                    cipher.notes += "\n\n" + text;
                }
            }
            const type = value["Entry Type"];
            if (type === "Password") {
                cipher.login.username = this.getValueOrDefault(value.Username);
                cipher.login.password = this.getValueOrDefault(value.Password);
                cipher.login.uris = this.makeUriArray(value["Site URL"]);
            }
            else if (type === "Credit Card") {
                cipher.type = CipherType.Card;
                cipher.card = new CardView();
                cipher.card.cardholderName = this.getValueOrDefault(value["Name on card"]);
                cipher.card.number = this.getValueOrDefault(value["Card Number"]);
                cipher.card.brand = CardView.getCardBrandByPatterns(cipher.card.number);
                cipher.card.code = this.getValueOrDefault(value.CVV);
                const expiry = this.getValueOrDefault(value.Expiry);
                if (!this.isNullOrWhitespace(expiry)) {
                    const expParts = expiry.split("/");
                    if (expParts.length > 1) {
                        cipher.card.expMonth = parseInt(expParts[0], null).toString();
                        cipher.card.expYear = (2000 + parseInt(expParts[1], null)).toString();
                    }
                }
            }
            this.convertToNoteIfNeeded(cipher);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/enpass/enpass-csv-importer.ts





class EnpassCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, false);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        let firstRow = true;
        results.forEach((value) => {
            if (value.length < 2 || (firstRow && (value[0] === "Title" || value[0] === "title"))) {
                firstRow = false;
                return;
            }
            const cipher = this.initLoginCipher();
            cipher.notes = this.getValueOrDefault(value[value.length - 1]);
            cipher.name = this.getValueOrDefault(value[0], "--");
            if (value.length === 2 ||
                (!this.containsField(value, "username") &&
                    !this.containsField(value, "password") &&
                    !this.containsField(value, "email") &&
                    !this.containsField(value, "url"))) {
                cipher.type = CipherType.SecureNote;
                cipher.secureNote = new SecureNoteView();
                cipher.secureNote.type = SecureNoteType.Generic;
            }
            if (this.containsField(value, "cardholder") &&
                this.containsField(value, "number") &&
                this.containsField(value, "expiry date")) {
                cipher.type = CipherType.Card;
                cipher.card = new CardView();
            }
            if (value.length > 2 && value.length % 2 === 0) {
                for (let i = 0; i < value.length - 2; i += 2) {
                    const fieldValue = value[i + 2];
                    if (this.isNullOrWhitespace(fieldValue)) {
                        continue;
                    }
                    const fieldName = value[i + 1];
                    const fieldNameLower = fieldName.toLowerCase();
                    if (cipher.type === CipherType.Login) {
                        if (fieldNameLower === "url" &&
                            (cipher.login.uris == null || cipher.login.uris.length === 0)) {
                            cipher.login.uris = this.makeUriArray(fieldValue);
                            continue;
                        }
                        else if ((fieldNameLower === "username" || fieldNameLower === "email") &&
                            this.isNullOrWhitespace(cipher.login.username)) {
                            cipher.login.username = fieldValue;
                            continue;
                        }
                        else if (fieldNameLower === "password" &&
                            this.isNullOrWhitespace(cipher.login.password)) {
                            cipher.login.password = fieldValue;
                            continue;
                        }
                        else if (fieldNameLower === "totp" && this.isNullOrWhitespace(cipher.login.totp)) {
                            cipher.login.totp = fieldValue;
                            continue;
                        }
                    }
                    else if (cipher.type === CipherType.Card) {
                        if (fieldNameLower === "cardholder" &&
                            this.isNullOrWhitespace(cipher.card.cardholderName)) {
                            cipher.card.cardholderName = fieldValue;
                            continue;
                        }
                        else if (fieldNameLower === "number" && this.isNullOrWhitespace(cipher.card.number)) {
                            cipher.card.number = fieldValue;
                            cipher.card.brand = CardView.getCardBrandByPatterns(cipher.card.number);
                            continue;
                        }
                        else if (fieldNameLower === "cvc" && this.isNullOrWhitespace(cipher.card.code)) {
                            cipher.card.code = fieldValue;
                            continue;
                        }
                        else if (fieldNameLower === "expiry date" &&
                            this.isNullOrWhitespace(cipher.card.expMonth) &&
                            this.isNullOrWhitespace(cipher.card.expYear)) {
                            if (this.setCardExpiration(cipher, fieldValue)) {
                                continue;
                            }
                        }
                        else if (fieldNameLower === "type") {
                            // Skip since brand was determined from number above
                            continue;
                        }
                    }
                    this.processKvp(cipher, fieldName, fieldValue);
                }
            }
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
    containsField(fields, name) {
        if (fields == null || name == null) {
            return false;
        }
        return (fields.filter((f) => !this.isNullOrWhitespace(f) && f.toLowerCase() === name.toLowerCase())
            .length > 0);
    }
}

;// ../../libs/importer/src/importers/enpass/enpass-json-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore





const androidUrlRegex = new RegExp("androidapp://.*==@", "g");
class EnpassJsonImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = JSON.parse(data);
        if (results == null || results.items == null || results.items.length === 0) {
            result.success = false;
            return Promise.resolve(result);
        }
        const foldersMap = new Map();
        const foldersIndexMap = new Map();
        const folderTree = this.buildFolderTree(results.folders);
        this.flattenFolderTree(null, folderTree, foldersMap);
        foldersMap.forEach((val, key) => {
            foldersIndexMap.set(key, result.folders.length);
            const f = new FolderView();
            f.name = val;
            result.folders.push(f);
        });
        results.items.forEach((item) => {
            if (item.folders != null && item.folders.length > 0 && foldersIndexMap.has(item.folders[0])) {
                result.folderRelationships.push([
                    result.ciphers.length,
                    foldersIndexMap.get(item.folders[0]),
                ]);
            }
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(item.title);
            cipher.favorite = item.favorite > 0;
            if (item.template_type != null && item.fields != null && item.fields.length > 0) {
                if (item.template_type.indexOf("login.") === 0 ||
                    item.template_type.indexOf("password.") === 0) {
                    this.processLogin(cipher, item.fields);
                }
                else if (item.template_type.indexOf("creditcard.") === 0) {
                    this.processCard(cipher, item.fields);
                }
                else if (item.template_type.indexOf("identity.") < 0 &&
                    item.fields.some((f) => f.type === "password" && !this.isNullOrWhitespace(f.value))) {
                    this.processLogin(cipher, item.fields);
                }
                else {
                    this.processNote(cipher, item.fields);
                }
            }
            const note = this.getValueOrDefault(item.note, "");
            if (note) {
                cipher.notes = note.trimEnd();
            }
            this.convertToNoteIfNeeded(cipher);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
    processLogin(cipher, fields) {
        const urls = [];
        fields.forEach((field) => {
            if (this.isNullOrWhitespace(field.value) || field.type === "section") {
                return;
            }
            if ((field.type === "username" || field.type === "email") &&
                this.isNullOrWhitespace(cipher.login.username)) {
                cipher.login.username = field.value;
            }
            else if (field.type === "password" && this.isNullOrWhitespace(cipher.login.password)) {
                cipher.login.password = field.value;
            }
            else if (field.type === "totp" && this.isNullOrWhitespace(cipher.login.totp)) {
                cipher.login.totp = field.value;
            }
            else if (field.type === "url") {
                urls.push(field.value);
            }
            else if (field.type === ".Android#") {
                let cleanedValue = field.value.startsWith("androidapp://")
                    ? field.value
                    : "androidapp://" + field.value;
                cleanedValue = cleanedValue.replace("android://", "");
                cleanedValue = cleanedValue.replace(androidUrlRegex, "androidapp://");
                urls.push(cleanedValue);
            }
            else {
                this.processKvp(cipher, field.label, field.value, field.sensitive === 1 ? FieldType.Hidden : FieldType.Text);
            }
        });
        cipher.login.uris = this.makeUriArray(urls);
    }
    processCard(cipher, fields) {
        cipher.card = new CardView();
        cipher.type = CipherType.Card;
        fields.forEach((field) => {
            if (this.isNullOrWhitespace(field.value) ||
                field.type === "section" ||
                field.type === "ccType") {
                return;
            }
            if (field.type === "ccName" && this.isNullOrWhitespace(cipher.card.cardholderName)) {
                cipher.card.cardholderName = field.value;
            }
            else if (field.type === "ccNumber" && this.isNullOrWhitespace(cipher.card.number)) {
                cipher.card.number = field.value;
                cipher.card.brand = CardView.getCardBrandByPatterns(cipher.card.number);
            }
            else if (field.type === "ccCvc" && this.isNullOrWhitespace(cipher.card.code)) {
                cipher.card.code = field.value;
            }
            else if (field.type === "ccExpiry" && this.isNullOrWhitespace(cipher.card.expYear)) {
                if (!this.setCardExpiration(cipher, field.value)) {
                    this.processKvp(cipher, field.label, field.value, field.sensitive === 1 ? FieldType.Hidden : FieldType.Text);
                }
            }
            else {
                this.processKvp(cipher, field.label, field.value, field.sensitive === 1 ? FieldType.Hidden : FieldType.Text);
            }
        });
    }
    processNote(cipher, fields) {
        fields.forEach((field) => {
            if (this.isNullOrWhitespace(field.value) || field.type === "section") {
                return;
            }
            this.processKvp(cipher, field.label, field.value, field.sensitive === 1 ? FieldType.Hidden : FieldType.Text);
        });
    }
    buildFolderTree(folders) {
        if (folders == null) {
            return [];
        }
        const folderTree = [];
        const map = new Map([]);
        folders.forEach((obj) => {
            map.set(obj.uuid, obj);
            obj.children = [];
        });
        folders.forEach((obj) => {
            if (obj.parent_uuid != null && obj.parent_uuid !== "" && map.has(obj.parent_uuid)) {
                map.get(obj.parent_uuid).children.push(obj);
            }
            else {
                folderTree.push(obj);
            }
        });
        return folderTree;
    }
    flattenFolderTree(titlePrefix, tree, map) {
        if (tree == null) {
            return;
        }
        tree.forEach((f) => {
            if (f.title != null && f.title.trim() !== "") {
                let title = f.title.trim();
                if (titlePrefix != null && titlePrefix.trim() !== "") {
                    title = titlePrefix + "/" + title;
                }
                map.set(f.uuid, title);
                if (f.children != null && f.children.length !== 0) {
                    this.flattenFolderTree(title, f.children, map);
                }
            }
        });
    }
}

;// ../../libs/importer/src/importers/enpass/index.ts



;// ../../libs/importer/src/importers/firefox-csv-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


class FirefoxCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results
            .filter((value) => {
            return value.url !== "chrome://FirefoxAccounts";
        })
            .forEach((value) => {
            const cipher = this.initLoginCipher();
            const url = this.getValueOrDefault(value.url, this.getValueOrDefault(value.hostname));
            cipher.name = this.getValueOrDefault(this.nameFromUrl(url), "--");
            cipher.login.username = this.getValueOrDefault(value.username);
            cipher.login.password = this.getValueOrDefault(value.password);
            cipher.login.uris = this.makeUriArray(url);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/fsecure/fsecure-fsk-types.ts
/**
 * Represents the different types of FSK entries.
 */
const FskEntryType = Object.freeze({
    Login: 1,
    CreditCard: 2,
});

;// ../../libs/importer/src/importers/fsecure/fsecure-fsk-importer.ts





class FSecureFskImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = JSON.parse(data);
        if (results == null || results.data == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        for (const [, value] of Object.entries(results.data)) {
            const cipher = this.parseEntry(value);
            if (cipher != undefined) {
                result.ciphers.push(cipher);
            }
        }
        result.success = true;
        return Promise.resolve(result);
    }
    parseEntry(entry) {
        const cipher = this.initLoginCipher();
        cipher.name = this.getValueOrDefault(entry.service);
        cipher.notes = this.getValueOrDefault(entry.notes);
        cipher.favorite = entry.favorite > 0;
        switch (entry.type) {
            case FskEntryType.Login:
                this.handleLoginEntry(entry, cipher);
                break;
            case FskEntryType.CreditCard:
                this.handleCreditCardEntry(entry, cipher);
                break;
            default:
                return undefined;
        }
        this.convertToNoteIfNeeded(cipher);
        this.cleanupCipher(cipher);
        return cipher;
    }
    handleLoginEntry(entry, cipher) {
        cipher.login.username = this.getValueOrDefault(entry.username);
        cipher.login.password = this.getValueOrDefault(entry.password);
        cipher.login.uris = this.makeUriArray(entry.url);
    }
    handleCreditCardEntry(entry, cipher) {
        cipher.type = CipherType.Card;
        cipher.card = new CardView();
        cipher.card.cardholderName = this.getValueOrDefault(entry.username);
        cipher.card.number = this.getValueOrDefault(entry.creditNumber);
        cipher.card.brand = CardView.getCardBrandByPatterns(cipher.card.number);
        cipher.card.code = this.getValueOrDefault(entry.creditCvv);
        if (!this.isNullOrWhitespace(entry.creditExpiry)) {
            if (!this.setCardExpiration(cipher, entry.creditExpiry)) {
                this.processKvp(cipher, "Expiration", entry.creditExpiry);
            }
        }
        if (!this.isNullOrWhitespace(entry.password)) {
            this.processKvp(cipher, "PIN", entry.password);
        }
    }
}

;// ../../libs/importer/src/importers/gnome-json-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


class GnomeJsonImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = JSON.parse(data);
        if (results == null || Object.keys(results).length === 0) {
            result.success = false;
            return Promise.resolve(result);
        }
        for (const keyRing in results) {
            if (!results.hasOwnProperty(keyRing) || // eslint-disable-line
                this.isNullOrWhitespace(keyRing) ||
                results[keyRing].length === 0) {
                continue;
            }
            results[keyRing].forEach((value) => {
                if (this.isNullOrWhitespace(value.display_name) ||
                    value.display_name.indexOf("http") !== 0) {
                    return;
                }
                this.processFolder(result, keyRing);
                const cipher = this.initLoginCipher();
                cipher.name = value.display_name.replace("http://", "").replace("https://", "");
                if (cipher.name.length > 30) {
                    cipher.name = cipher.name.substring(0, 30);
                }
                cipher.login.password = this.getValueOrDefault(value.secret);
                cipher.login.uris = this.makeUriArray(value.display_name);
                if (value.attributes != null) {
                    cipher.login.username =
                        value.attributes != null
                            ? this.getValueOrDefault(value.attributes.username_value)
                            : null;
                    for (const attr in value.attributes) {
                        if (!value.attributes.hasOwnProperty(attr) || // eslint-disable-line
                            attr === "username_value" ||
                            attr === "xdg:schema") {
                            continue;
                        }
                        this.processKvp(cipher, attr, value.attributes[attr]);
                    }
                }
                this.convertToNoteIfNeeded(cipher);
                this.cleanupCipher(cipher);
                result.ciphers.push(cipher);
            });
        }
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/kaspersky-txt-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


const NotesHeader = "Notes\n\n";
const ApplicationsHeader = "Applications\n\n";
const WebsitesHeader = "Websites\n\n";
const Delimiter = "\n---\n";
class KasperskyTxtImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        let notesData;
        let applicationsData;
        let websitesData;
        let workingData = this.splitNewLine(data).join("\n");
        if (workingData.indexOf(NotesHeader) !== -1) {
            const parts = workingData.split(NotesHeader);
            if (parts.length > 1) {
                workingData = parts[0];
                notesData = parts[1];
            }
        }
        if (workingData.indexOf(ApplicationsHeader) !== -1) {
            const parts = workingData.split(ApplicationsHeader);
            if (parts.length > 1) {
                workingData = parts[0];
                applicationsData = parts[1];
            }
        }
        if (workingData.indexOf(WebsitesHeader) === 0) {
            const parts = workingData.split(WebsitesHeader);
            if (parts.length > 1) {
                workingData = parts[0];
                websitesData = parts[1];
            }
        }
        const notes = this.parseDataCategory(notesData);
        const applications = this.parseDataCategory(applicationsData);
        const websites = this.parseDataCategory(websitesData);
        notes.forEach((n) => {
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(n.get("Name"));
            cipher.notes = this.getValueOrDefault(n.get("Text"));
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        websites.concat(applications).forEach((w) => {
            const cipher = this.initLoginCipher();
            const nameKey = w.has("Website name") ? "Website name" : "Application";
            cipher.name = this.getValueOrDefault(w.get(nameKey), "");
            if (!this.isNullOrWhitespace(w.get("Login name"))) {
                if (!this.isNullOrWhitespace(cipher.name)) {
                    cipher.name += ": ";
                }
                cipher.name += w.get("Login name");
            }
            cipher.notes = this.getValueOrDefault(w.get("Comment"));
            if (w.has("Website URL")) {
                cipher.login.uris = this.makeUriArray(w.get("Website URL"));
            }
            cipher.login.username = this.getValueOrDefault(w.get("Login"));
            cipher.login.password = this.getValueOrDefault(w.get("Password"));
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
    parseDataCategory(data) {
        if (this.isNullOrWhitespace(data) || data.indexOf(Delimiter) === -1) {
            return [];
        }
        const items = [];
        data.split(Delimiter).forEach((p) => {
            if (p.indexOf("\n") === -1) {
                return;
            }
            const item = new Map();
            let itemComment;
            let itemCommentKey;
            p.split("\n").forEach((l) => {
                if (itemComment != null) {
                    itemComment += "\n" + l;
                    return;
                }
                const colonIndex = l.indexOf(":");
                let key;
                let val;
                if (colonIndex === -1) {
                    return;
                }
                else {
                    key = l.substring(0, colonIndex);
                    if (l.length > colonIndex + 1) {
                        val = l.substring(colonIndex + 2);
                    }
                }
                if (key != null) {
                    item.set(key, val);
                }
                if (key === "Comment" || key === "Text") {
                    itemComment = val;
                    itemCommentKey = key;
                }
            });
            if (itemComment != null && itemCommentKey != null) {
                item.set(itemCommentKey, itemComment);
            }
            if (item.size === 0) {
                return;
            }
            items.push(item);
        });
        return items;
    }
}

;// ../../libs/importer/src/importers/keepass2-xml-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore





class KeePass2XmlImporter extends BaseImporter {
    constructor() {
        super(...arguments);
        this.result = new ImportResult();
    }
    parse(data) {
        const doc = this.parseXml(data);
        if (doc == null) {
            this.result.success = false;
            return Promise.resolve(this.result);
        }
        //Note: The doc.querySelector("KeePassFile > Root > Group") no longers works on node and we have to breakdown the query by nodes
        const KeePassFileNode = doc.querySelector("KeePassFile");
        if (KeePassFileNode == null) {
            this.result.errorMessage = "Missing `KeePassFile` node.";
            this.result.success = false;
            return Promise.resolve(this.result);
        }
        const RootNode = KeePassFileNode.querySelector("Root");
        if (RootNode == null) {
            this.result.errorMessage = "Missing `KeePassFile > Root` node.";
            this.result.success = false;
            return Promise.resolve(this.result);
        }
        const rootGroup = RootNode.querySelector("Group");
        if (rootGroup == null) {
            this.result.errorMessage = "Missing `KeePassFile > Root > Group` node.";
            this.result.success = false;
            return Promise.resolve(this.result);
        }
        this.traverse(rootGroup, true, "");
        if (this.organization) {
            this.moveFoldersToCollections(this.result);
        }
        this.result.success = true;
        return Promise.resolve(this.result);
    }
    traverse(node, isRootNode, groupPrefixName) {
        const folderIndex = this.result.folders.length;
        let groupName = groupPrefixName;
        if (!isRootNode) {
            if (groupName !== "") {
                groupName += "/";
            }
            const nameEl = this.querySelectorDirectChild(node, "Name");
            groupName += nameEl == null ? "-" : nameEl.textContent;
            const folder = new FolderView();
            folder.name = groupName;
            this.result.folders.push(folder);
        }
        this.querySelectorAllDirectChild(node, "Entry").forEach((entry) => {
            const cipherIndex = this.result.ciphers.length;
            const cipher = this.initLoginCipher();
            this.querySelectorAllDirectChild(entry, "String").forEach((entryString) => {
                const valueEl = this.querySelectorDirectChild(entryString, "Value");
                const value = valueEl != null ? valueEl.textContent : null;
                if (this.isNullOrWhitespace(value)) {
                    return;
                }
                const keyEl = this.querySelectorDirectChild(entryString, "Key");
                const key = keyEl != null ? keyEl.textContent : null;
                if (key === "URL") {
                    cipher.login.uris = this.makeUriArray(value);
                }
                else if (key === "UserName") {
                    cipher.login.username = value;
                }
                else if (key === "Password") {
                    cipher.login.password = value;
                }
                else if (key === "otp") {
                    cipher.login.totp = value.replace("key=", "");
                }
                else if (key === "Title") {
                    cipher.name = value;
                }
                else if (key === "Notes") {
                    cipher.notes += value + "\n";
                }
                else {
                    const attrs = valueEl.attributes;
                    const isProtected = attrs.length > 0 &&
                        attrs.ProtectInMemory != null &&
                        attrs.ProtectInMemory.value === "True";
                    if (isProtected) {
                        // Protected fields should always be imported as hidden fields,
                        // regardless of length or newlines (fixes #16897)
                        if (cipher.fields == null) {
                            cipher.fields = [];
                        }
                        const field = new FieldView();
                        field.type = FieldType.Hidden;
                        field.name = key;
                        field.value = value;
                        cipher.fields.push(field);
                    }
                    else {
                        this.processKvp(cipher, key, value, FieldType.Text);
                    }
                }
            });
            this.cleanupCipher(cipher);
            this.result.ciphers.push(cipher);
            if (!isRootNode) {
                this.result.folderRelationships.push([cipherIndex, folderIndex]);
            }
        });
        this.querySelectorAllDirectChild(node, "Group").forEach((group) => {
            this.traverse(group, false, groupName);
        });
    }
}

;// ../../libs/importer/src/importers/keepassx-csv-importer.ts


class KeePassXCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            if (this.isNullOrWhitespace(value.Title)) {
                return;
            }
            value.Group =
                !this.isNullOrWhitespace(value.Group) && value.Group.startsWith("Root/")
                    ? value.Group.replace("Root/", "")
                    : value.Group;
            const groupName = !this.isNullOrWhitespace(value.Group) ? value.Group : null;
            this.processFolder(result, groupName);
            const cipher = this.initLoginCipher();
            cipher.notes = this.getValueOrDefault(value.Notes);
            cipher.name = this.getValueOrDefault(value.Title, "--");
            cipher.login.username = this.getValueOrDefault(value.Username);
            cipher.login.password = this.getValueOrDefault(value.Password);
            cipher.login.uris = this.makeUriArray(value.URL);
            cipher.login.totp = this.getValueOrDefault(value.TOTP);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/keeper/keeper-csv-importer.ts


class KeeperCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, false);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            if (value.length < 6) {
                return;
            }
            this.processFolder(result, value[0]);
            const cipher = this.initLoginCipher();
            const notes = this.getValueOrDefault(value[5]);
            if (notes) {
                cipher.notes = notes.trimEnd();
            }
            cipher.name = this.getValueOrDefault(value[1], "--");
            cipher.login.username = this.getValueOrDefault(value[2]);
            cipher.login.password = this.getValueOrDefault(value[3]);
            cipher.login.uris = this.makeUriArray(value[4]);
            if (value.length > 7) {
                // we have some custom fields.
                for (let i = 7; i < value.length; i = i + 2) {
                    if (value[i] == "TFC:Keeper") {
                        cipher.login.totp = value[i + 1];
                    }
                    else {
                        this.processKvp(cipher, value[i], value[i + 1]);
                    }
                }
            }
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/keeper/keeper-json-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore








class KeeperJsonImporter extends BaseImporter {
    constructor() {
        super(...arguments);
        this.references = new Map();
        this.idToCipher = new Map();
    }
    parse(data) {
        var _a;
        const result = new ImportResult();
        const keeperExport = JSON.parse(data);
        if (!((_a = keeperExport === null || keeperExport === void 0 ? void 0 : keeperExport.records) === null || _a === void 0 ? void 0 : _a.length)) {
            result.success = false;
            return Promise.resolve(result);
        }
        this.parseSharedFolders(keeperExport, result);
        this.parseRecords(keeperExport, result);
        this.resolveReferences();
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
    parseSharedFolders(keeperExport, result) {
        if (!keeperExport.shared_folders) {
            return;
        }
        keeperExport.shared_folders.forEach((folder) => {
            var _a;
            this.processFolder(result, this.sanitizeFolderName((_a = folder.path) !== null && _a !== void 0 ? _a : ""), false);
        });
    }
    parseRecords(keeperExport, result) {
        keeperExport.records.forEach((record) => {
            this.parseFolders(result, record);
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(record.title);
            cipher.notes = this.getValueOrDefault(record.notes);
            cipher.login.username = this.getValueOrDefault(record.login);
            cipher.login.password = this.getValueOrDefault(record.password);
            cipher.login.uris = this.makeUriArray(record.login_url);
            // Force type based on the record type
            switch (record.$type) {
                case "bankCard":
                    this.importBankCard(record, cipher);
                    break;
                case "driverLicense":
                    this.importDriverLicense(record, cipher);
                    break;
                case "ssnCard":
                    this.importSsnCard(record, cipher);
                    break;
                case "passport":
                    this.importPassport(record, cipher);
                    break;
                case "sshKeys":
                    // In Bitwarden the ssh key is supposed to be valid.
                    // So we only set the type if we can actually import a key.
                    if (!this.importSshKey(record, cipher)) {
                        // Otherwise, fallback to secure note
                        cipher.type = CipherType.SecureNote;
                        // Make sure the passphrase is not lost, if any. The key pair will be imported as a custom field.
                        this.addField(cipher, "Passphrase", cipher.login.password, FieldType.Hidden);
                    }
                    break;
            }
            if (record.custom_fields) {
                this.importCustomFields(record.custom_fields, cipher);
            }
            if (record.uid && record.references) {
                const refs = [];
                for (const [key, values] of Object.entries(record.references)) {
                    let [type] = this.parseFieldKey(key);
                    // Web exporter appends "Ref" to the type names
                    if (type.endsWith("Ref")) {
                        type = type.substring(0, type.length - 3);
                    }
                    refs.push(...this.makeArray(values).map((id) => ({ id: id, type: type })));
                }
                if (refs.length > 0) {
                    this.references.set(record.uid, refs);
                }
            }
            this.convertToNoteIfNeeded(cipher);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
            // This is needed for resolving references later
            if (record.uid) {
                this.idToCipher.set(record.uid, cipher);
            }
        });
    }
    resolveReferences() {
        var _a;
        for (const [uid, refs] of this.references) {
            const cipher = this.idToCipher.get(uid);
            if (!cipher) {
                continue;
            }
            for (const { id, type } of refs) {
                const refCipher = this.idToCipher.get(id);
                if (!refCipher) {
                    continue;
                }
                const value = ((_a = this.findFieldByName(refCipher, type)) === null || _a === void 0 ? void 0 : _a.value) || "";
                if (value) {
                    this.addField(cipher, type, value);
                }
            }
        }
    }
    findFieldByName(cipher, name) {
        return cipher.fields.find((f) => f.name === name) || null;
    }
    importBankCard(record, cipher) {
        cipher.type = CipherType.Card;
        cipher.card.cardholderName = this.findCustomField(record.custom_fields, "$text:cardholderName");
        cipher.card.number = this.findCustomField(record.custom_fields, "$paymentCard/cardNumber");
        cipher.card.code = this.findCustomField(record.custom_fields, "$paymentCard/cardSecurityCode");
        cipher.card.brand = CardView.getCardBrandByPatterns(cipher.card.number);
        const expDate = this.findCustomField(record.custom_fields, "$paymentCard/cardExpirationDate");
        if (expDate) {
            const expDateParts = expDate.split("/");
            if (expDateParts.length === 2) {
                cipher.card.expMonth = expDateParts[0];
                cipher.card.expYear = expDateParts[1];
            }
            else {
                this.addField(cipher, "Expiration date", expDate);
            }
        }
        const pinCode = this.findCustomField(record.custom_fields, "$pinCode");
        if (pinCode) {
            this.addField(cipher, "PIN", pinCode, FieldType.Hidden);
        }
        this.copyLoginPropertiesAsCustomFields(cipher);
        // These should not be imported as custom fields since they are mapped to card properties
        this.deleteTopLevelCustomField(record.custom_fields, "$paymentCard");
        this.deleteTopLevelCustomField(record.custom_fields, "$text:cardholderName");
        this.deleteTopLevelCustomField(record.custom_fields, "$pinCode");
    }
    importSshKey(record, cipher) {
        const privateKey = this.findCustomField(record.custom_fields, "$keyPair/privateKey");
        if (!privateKey) {
            return false;
        }
        let keyView = null;
        try {
            keyView = (0,bitwarden_wasm_internal_bg/* import_ssh_key */.bnN)(privateKey, cipher.login.password);
        }
        catch (_a) {
            this.logService.warning(`Unable to import SSH key (id: ${record.uid}, title: ${record.title})`);
            return false;
        }
        if (!keyView) {
            return false;
        }
        cipher.type = CipherType.SshKey;
        cipher.sshKey.privateKey = keyView.privateKey;
        cipher.sshKey.publicKey = keyView.publicKey;
        cipher.sshKey.keyFingerprint = keyView.fingerprint;
        this.copyLoginPropertiesAsCustomFields(cipher);
        const hostName = this.findCustomField(record.custom_fields, "$host/hostName");
        if (hostName) {
            this.addField(cipher, "Hostname", hostName);
        }
        const port = this.findCustomField(record.custom_fields, "$host/port");
        if (port) {
            this.addField(cipher, "Port", port);
        }
        // These should not be imported as custom fields since they are mapped to ssh key properties
        this.deleteTopLevelCustomField(record.custom_fields, "$keyPair");
        this.deleteTopLevelCustomField(record.custom_fields, "$host");
        return true;
    }
    importDriverLicense(record, cipher) {
        cipher.type = CipherType.Identity;
        cipher.identity = new IdentityView();
        cipher.identity.licenseNumber = this.findCustomField(record.custom_fields, "$accountNumber:dlNumber");
        this.importIdentityName(record, cipher);
        this.copyLoginPropertiesAsCustomFields(cipher);
        this.deleteTopLevelCustomField(record.custom_fields, "$accountNumber:dlNumber");
    }
    importSsnCard(record, cipher) {
        cipher.type = CipherType.Identity;
        cipher.identity = new IdentityView();
        cipher.identity.ssn = this.findCustomField(record.custom_fields, "$accountNumber:identityNumber");
        this.importIdentityName(record, cipher);
        this.copyLoginPropertiesAsCustomFields(cipher);
        this.deleteTopLevelCustomField(record.custom_fields, "$accountNumber:identityNumber");
    }
    importPassport(record, cipher) {
        cipher.type = CipherType.Identity;
        cipher.identity = new IdentityView();
        cipher.identity.passportNumber = this.findCustomField(record.custom_fields, "$accountNumber:passportNumber");
        this.importIdentityName(record, cipher);
        this.copyLoginPropertiesAsCustomFields(cipher);
        this.deleteTopLevelCustomField(record.custom_fields, "$accountNumber:passportNumber");
    }
    importIdentityName(record, cipher) {
        cipher.identity.firstName = this.findCustomField(record.custom_fields, "$name/first");
        cipher.identity.middleName = this.findCustomField(record.custom_fields, "$name/middle");
        cipher.identity.lastName = this.findCustomField(record.custom_fields, "$name/last");
        this.deleteTopLevelCustomField(record.custom_fields, "$name");
    }
    copyLoginPropertiesAsCustomFields(cipher) {
        if (!this.isNullOrWhitespace(cipher.login.username)) {
            this.addField(cipher, "Username", cipher.login.username);
            cipher.login.username = undefined;
        }
        if (!this.isNullOrWhitespace(cipher.login.password)) {
            this.addField(cipher, "Password", cipher.login.password, FieldType.Hidden);
            cipher.login.password = undefined;
        }
        if (cipher.login.uris) {
            cipher.login.uris.forEach((uri, index) => {
                this.addField(cipher, "URL", uri.uri);
            });
            cipher.login.uris = [];
        }
    }
    // Matches by the full key with only the trailing `:digit` suffix stripped.
    // Supports nested path lookups via `/` (e.g. "$paymentCard/cardNumber").
    // Used for keys like "$paymentCard::1" where the full prefix is known.
    findCustomField(customFields, path) {
        if (customFields == null) {
            return "";
        }
        let root = customFields;
        for (const part of path.split("/")) {
            const keys = Object.keys(root);
            if (keys.length === 0) {
                return "";
            }
            const key = keys.find((k) => k.replace(/:?:\d$/, "") === part);
            if (!key || root[key] == null) {
                return "";
            }
            root = root[key];
        }
        return root.toString();
    }
    deleteTopLevelCustomField(customFields, name) {
        if (customFields == null) {
            return;
        }
        const key = Object.keys(customFields).find((k) => k.replace(/:?:\d$/, "") === name);
        if (key) {
            delete customFields[key];
        }
    }
    importCustomFields(customFields, cipher) {
        for (const [originalKey, originalValue] of Object.entries(customFields)) {
            const [type, name] = this.parseFieldKey(originalKey);
            // These handle arrays internally
            if (this.tryImportArrayField(type, originalValue, cipher)) {
                continue;
            }
            const importedName = name || type || originalKey;
            const values = this.makeArray(originalValue);
            for (const value of values) {
                // These expand into multiple fields
                if (this.tryImportExpandingField(type, value, cipher)) {
                    continue;
                }
                // Import as a single field with JSON.stringify as the last resort fallback
                this.importSingleField(type, importedName, value, cipher);
            }
        }
    }
    tryImportArrayField(type, originalValue, cipher) {
        switch (type) {
            case "oneTimeCode":
                {
                    const totps = this.makeArray(originalValue);
                    if (totps.length === 0) {
                        break;
                    }
                    // Login has a dedicated TOTP field. All others get added as custom fields.
                    if (cipher.type === CipherType.Login) {
                        cipher.login.totp = totps[0];
                        totps.shift();
                    }
                    totps.forEach((code) => {
                        this.addField(cipher, "TOTP", code, FieldType.Hidden);
                    });
                }
                break;
            case "url":
                {
                    const urls = this.makeUriArray(originalValue);
                    if (cipher.type === CipherType.Login) {
                        cipher.login.uris.push(...urls);
                    }
                    else {
                        urls.forEach((url) => {
                            this.addField(cipher, "URL", url.uri);
                        });
                    }
                }
                break;
            default:
                return false;
        }
        return true;
    }
    tryImportExpandingField(type, originalValue, cipher) {
        switch (type) {
            case "host":
                {
                    const { hostName, port } = originalValue;
                    this.addField(cipher, "Hostname", hostName);
                    this.addField(cipher, "Port", port);
                }
                break;
            case "keyPair":
                {
                    const { publicKey, privateKey } = originalValue;
                    this.addField(cipher, "Public key", publicKey);
                    this.addField(cipher, "Private key", privateKey, FieldType.Hidden);
                }
                break;
            case "securityQuestion":
                {
                    for (const { question, answer } of this.makeArray(originalValue)) {
                        this.addField(cipher, "Security question", question);
                        this.addField(cipher, "Security question answer", answer, FieldType.Hidden);
                    }
                }
                break;
            case "appFiller":
                // Ignored since it's an implementation detail of Keeper
                break;
            default:
                return false;
        }
        return true;
    }
    importSingleField(type, importedName, value, cipher) {
        let importedValue = this.convertToFieldValue(value);
        let importedType = FieldType.Text;
        switch (type) {
            case "date":
            case "birthDate":
            case "expirationDate":
                importedValue = this.parseDate(value);
                break;
            case "name":
                {
                    const { first, middle, last } = value;
                    importedValue = [first, middle, last]
                        .filter((x) => x)
                        .join(" ")
                        .trim();
                }
                break;
            case "address":
                {
                    const { street1, street2, city, state, zip, country } = value;
                    importedValue = [street1, street2, city, state, zip, country]
                        .filter((x) => x)
                        .join(", ")
                        .trim();
                }
                break;
            case "phone":
                {
                    const { region, number, ext, type } = value;
                    const parts = [];
                    if (region) {
                        // TODO: Convert to +<code> format?
                        parts.push(`(${region})`);
                    }
                    if (number) {
                        parts.push(number);
                    }
                    if (ext) {
                        parts.push(`ext. ${ext}`);
                    }
                    if (type) {
                        parts.push(`(${type})`);
                    }
                    importedValue = parts.join(" ").trim();
                }
                break;
            case "bankAccount":
                {
                    const { accountType, otherType, accountNumber, routingNumber } = value;
                    const parts = [];
                    const type = otherType || accountType;
                    if (type) {
                        parts.push(`Type: ${type}`);
                    }
                    if (accountNumber) {
                        parts.push(`Account Number: ${accountNumber}`);
                    }
                    if (routingNumber) {
                        parts.push(`Routing Number: ${routingNumber}`);
                    }
                    importedValue = parts.join(", ").trim();
                }
                break;
            case "pinCode":
            case "secret":
                importedType = FieldType.Hidden;
                break;
            default:
                // Do nothing, default conversion is fine
                break;
        }
        this.addField(cipher, importedName, importedValue, importedType);
    }
    parseDate(timestamp) {
        const date = new Date(timestamp);
        return isNaN(date.getTime()) ? "" : date.toLocaleString();
    }
    // This function parses custom field keys of the form:
    // $<type>:<name>:<suffix> and returns [type, name]
    // It handles a bunch of edge cases as well. See tests for examples.
    // This function is modeled after the original implementation.
    parseFieldKey(key) {
        if (this.isNullOrWhitespace(key)) {
            return ["", ""];
        }
        let fieldType = "";
        let fieldName = "";
        if (key[0] === "$") {
            const pos = key.indexOf(":");
            if (pos > 0) {
                fieldType = key.substring(1, pos).trim();
                fieldName = key.substring(pos + 1).trim();
            }
            else {
                fieldType = key.substring(1).trim();
                fieldName = "";
            }
        }
        else {
            fieldType = "";
            fieldName = key;
        }
        if (fieldName.length >= 2 &&
            fieldName[fieldName.length - 2] === ":" &&
            /\d/.test(fieldName[fieldName.length - 1])) {
            fieldName = fieldName.substring(0, fieldName.length - 2);
        }
        return [fieldType, fieldName];
    }
    addField(cipher, name, value, type = FieldType.Text) {
        if (!value) {
            return;
        }
        const field = new FieldView();
        field.type = type;
        field.name = name;
        field.value = this.convertToFieldValue(value);
        cipher.fields.push(field);
    }
    // Just to be safe, value come in all kinds of flavors
    convertToFieldValue(value) {
        if (typeof value === "string") {
            return value;
        }
        try {
            return JSON.stringify(value);
        }
        catch (_a) {
            // Fallthrough
        }
        return "";
    }
    makeArray(value) {
        if (Array.isArray(value)) {
            return value;
        }
        if (value != null) {
            return [value];
        }
        return [];
    }
    parseFolders(result, record) {
        if (!record.folders) {
            return;
        }
        record.folders.forEach((item) => {
            if (item.folder != null) {
                this.processFolder(result, this.sanitizeFolderName(item.folder));
            }
            if (item.shared_folder != null) {
                this.processFolder(result, this.sanitizeFolderName(item.shared_folder));
            }
        });
    }
    sanitizeFolderName(name) {
        // `\` and `/` are reserved characters in Bitwarden, but valid in Keeper, replace them with `-`.
        return name.replaceAll("\\\\", "-").replaceAll("/", "-");
    }
}

;// ../../libs/importer/src/importers/keeper/index.ts



;// ../../libs/importer/src/importers/lastpass/lastpass-csv-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore









class LastPassCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            const cipherIndex = result.ciphers.length;
            let folderIndex = result.folders.length;
            let grouping = value.grouping;
            if (grouping != null) {
                // eslint-disable-next-line
                grouping = grouping.replace(/\\/g, "/").replace(/[\x00-\x1F\x7F-\x9F]/g, "");
            }
            const hasFolder = this.getValueOrDefault(grouping, "(none)") !== "(none)";
            let addFolder = hasFolder;
            if (hasFolder) {
                for (let i = 0; i < result.folders.length; i++) {
                    if (result.folders[i].name === grouping) {
                        addFolder = false;
                        folderIndex = i;
                        break;
                    }
                }
            }
            const cipher = this.buildBaseCipher(value);
            if (cipher.type === CipherType.Login) {
                cipher.notes = this.getValueOrDefault(value.extra);
                cipher.login = new LoginView();
                cipher.login.uris = this.makeUriArray(value.url);
                cipher.login.username = this.getValueOrDefault(value.username);
                cipher.login.password = this.getValueOrDefault(value.password);
                cipher.login.totp = this.getValueOrDefault(value.totp);
            }
            else if (cipher.type === CipherType.SecureNote) {
                this.parseSecureNote(value, cipher);
            }
            else if (cipher.type === CipherType.Card) {
                cipher.card = this.parseCard(value);
                cipher.notes = this.getValueOrDefault(value.notes);
            }
            else if (cipher.type === CipherType.Identity) {
                cipher.identity = this.parseIdentity(value);
                cipher.notes = this.getValueOrDefault(value.notes);
                if (!this.isNullOrWhitespace(value.ccnum)) {
                    // there is a card on this identity too
                    const cardCipher = this.buildBaseCipher(value);
                    cardCipher.identity = null;
                    cardCipher.type = CipherType.Card;
                    cardCipher.card = this.parseCard(value);
                    result.ciphers.push(cardCipher);
                }
            }
            result.ciphers.push(cipher);
            if (addFolder) {
                const f = new FolderView();
                f.name = grouping;
                result.folders.push(f);
            }
            if (hasFolder) {
                result.folderRelationships.push([cipherIndex, folderIndex]);
            }
        });
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
    buildBaseCipher(value) {
        const cipher = new CipherView();
        // eslint-disable-next-line
        if (value.hasOwnProperty("profilename") && value.hasOwnProperty("profilelanguage")) {
            // form fill
            cipher.favorite = false;
            cipher.name = this.getValueOrDefault(value.profilename, "--");
            cipher.type = CipherType.Card;
            if (!this.isNullOrWhitespace(value.title) ||
                !this.isNullOrWhitespace(value.firstname) ||
                !this.isNullOrWhitespace(value.lastname) ||
                !this.isNullOrWhitespace(value.address1) ||
                !this.isNullOrWhitespace(value.phone) ||
                !this.isNullOrWhitespace(value.username) ||
                !this.isNullOrWhitespace(value.email)) {
                cipher.type = CipherType.Identity;
            }
        }
        else {
            // site or secure note
            cipher.favorite = !this.organization && this.getValueOrDefault(value.fav, "0") === "1";
            cipher.name = this.getValueOrDefault(value.name, "--");
            cipher.type = value.url === "http://sn" ? CipherType.SecureNote : CipherType.Login;
        }
        return cipher;
    }
    parseCard(value) {
        const card = new CardView();
        card.cardholderName = this.getValueOrDefault(value.ccname);
        card.number = this.getValueOrDefault(value.ccnum);
        card.code = this.getValueOrDefault(value.cccsc);
        card.brand = CardView.getCardBrandByPatterns(card.number);
        if (!this.isNullOrWhitespace(value.ccexp) && value.ccexp.indexOf("-") > -1) {
            const ccexpParts = value.ccexp.split("-");
            if (ccexpParts.length > 1) {
                card.expYear = ccexpParts[0];
                card.expMonth = ccexpParts[1];
                if (card.expMonth.length === 2 && card.expMonth[0] === "0") {
                    card.expMonth = card.expMonth[1];
                }
            }
        }
        return card;
    }
    parseIdentity(value) {
        const identity = new IdentityView();
        identity.title = this.getValueOrDefault(value.title);
        identity.firstName = this.getValueOrDefault(value.firstname);
        identity.middleName = this.getValueOrDefault(value.middlename);
        identity.lastName = this.getValueOrDefault(value.lastname);
        identity.username = this.getValueOrDefault(value.username);
        identity.company = this.getValueOrDefault(value.company);
        identity.ssn = this.getValueOrDefault(value.ssn);
        identity.address1 = this.getValueOrDefault(value.address1);
        identity.address2 = this.getValueOrDefault(value.address2);
        identity.address3 = this.getValueOrDefault(value.address3);
        identity.city = this.getValueOrDefault(value.city);
        identity.state = this.getValueOrDefault(value.state);
        identity.postalCode = this.getValueOrDefault(value.zip);
        identity.country = this.getValueOrDefault(value.country);
        identity.email = this.getValueOrDefault(value.email);
        identity.phone = this.getValueOrDefault(value.phone);
        if (!this.isNullOrWhitespace(identity.title)) {
            identity.title = identity.title.charAt(0).toUpperCase() + identity.title.slice(1);
        }
        return identity;
    }
    parseSecureNote(value, cipher) {
        const extraParts = this.splitNewLine(value.extra);
        let processedNote = false;
        if (extraParts.length) {
            const typeParts = extraParts[0].split(":");
            if (typeParts.length > 1 &&
                typeParts[0] === "NoteType" &&
                (typeParts[1] === "Credit Card" || typeParts[1] === "Address")) {
                if (typeParts[1] === "Credit Card") {
                    const mappedData = this.parseSecureNoteMapping(cipher, extraParts, {
                        Number: "number",
                        "Name on Card": "cardholderName",
                        "Security Code": "code",
                        // LP provides date in a format like 'June,2020'
                        // Store in expMonth, then parse and modify
                        "Expiration Date": "expMonth",
                    });
                    if (this.isNullOrWhitespace(mappedData.expMonth) || mappedData.expMonth === ",") {
                        // No expiration data
                        mappedData.expMonth = undefined;
                    }
                    else {
                        const [monthString, year] = mappedData.expMonth.split(",");
                        // Parse month name into number
                        if (!this.isNullOrWhitespace(monthString)) {
                            const month = new Date(Date.parse(monthString.trim() + " 1, 2012")).getMonth() + 1;
                            if (isNaN(month)) {
                                mappedData.expMonth = undefined;
                            }
                            else {
                                mappedData.expMonth = month.toString();
                            }
                        }
                        else {
                            mappedData.expMonth = undefined;
                        }
                        if (!this.isNullOrWhitespace(year)) {
                            mappedData.expYear = year;
                        }
                    }
                    cipher.type = CipherType.Card;
                    cipher.card = new CardView();
                    Object.assign(cipher.card, mappedData);
                }
                else if (typeParts[1] === "Address") {
                    const mappedData = this.parseSecureNoteMapping(cipher, extraParts, {
                        Title: "title",
                        "First Name": "firstName",
                        "Last Name": "lastName",
                        "Middle Name": "middleName",
                        Company: "company",
                        "Address 1": "address1",
                        "Address 2": "address2",
                        "Address 3": "address3",
                        "City / Town": "city",
                        State: "state",
                        "Zip / Postal Code": "postalCode",
                        Country: "country",
                        "Email Address": "email",
                        Username: "username",
                    });
                    cipher.type = CipherType.Identity;
                    cipher.identity = new IdentityView();
                    Object.assign(cipher.identity, mappedData);
                }
                processedNote = true;
            }
        }
        if (!processedNote) {
            cipher.secureNote = new SecureNoteView();
            cipher.secureNote.type = SecureNoteType.Generic;
            cipher.notes = this.getValueOrDefault(value.extra);
        }
    }
    parseSecureNoteMapping(cipher, extraParts, map) {
        const dataObj = {};
        let processingNotes = false;
        extraParts.forEach((extraPart) => {
            let key = null;
            let val = null;
            if (!processingNotes) {
                if (this.isNullOrWhitespace(extraPart)) {
                    return;
                }
                const colonIndex = extraPart.indexOf(":");
                if (colonIndex === -1) {
                    key = extraPart;
                }
                else {
                    key = extraPart.substring(0, colonIndex);
                    if (extraPart.length > colonIndex) {
                        val = extraPart.substring(colonIndex + 1);
                    }
                }
                if (this.isNullOrWhitespace(key) || this.isNullOrWhitespace(val) || key === "NoteType") {
                    return;
                }
            }
            if (processingNotes) {
                cipher.notes += "\n" + extraPart;
            }
            else if (key === "Notes") {
                if (!this.isNullOrWhitespace(cipher.notes)) {
                    cipher.notes += "\n" + val;
                }
                else {
                    cipher.notes = val;
                }
                processingNotes = true;
                // eslint-disable-next-line
            }
            else if (map.hasOwnProperty(key)) {
                dataObj[map[key]] = val;
            }
            else {
                this.processKvp(cipher, key, val);
            }
        });
        return dataObj;
    }
}

;// ../../libs/importer/src/importers/lastpass/index.ts


;// ../../libs/importer/src/importers/logmeonce-csv-importer.ts


class LogMeOnceCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, false);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            if (value.length < 4) {
                return;
            }
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(value[0], "--");
            cipher.login.username = this.getValueOrDefault(value[2]);
            cipher.login.password = this.getValueOrDefault(value[3]);
            cipher.login.uris = this.makeUriArray(value[1]);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/meldium-csv-importer.ts


class MeldiumCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(value.DisplayName, "--");
            cipher.notes = this.getValueOrDefault(value.Notes);
            cipher.login.username = this.getValueOrDefault(value.UserName);
            cipher.login.password = this.getValueOrDefault(value.Password);
            cipher.login.uris = this.makeUriArray(value.Url);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/msecure-csv-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore




class MSecureCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, false, { delimiter: "," });
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            if (value.length < 3) {
                return;
            }
            const folderName = this.getValueOrDefault(value[2], "Unassigned") !== "Unassigned" ? value[2] : null;
            this.processFolder(result, folderName);
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(value[0].split("|")[0], "--");
            if (value[1] === "Web Logins" || value[1] === "Login") {
                cipher.login.username = this.getValueOrDefault(this.splitValueRetainingLastPart(value[5]));
                cipher.login.uris = this.makeUriArray(this.splitValueRetainingLastPart(value[4]));
                cipher.login.password = this.getValueOrDefault(this.splitValueRetainingLastPart(value[6]));
                cipher.notes = !this.isNullOrWhitespace(value[3]) ? value[3].split("\\n").join("\n") : null;
            }
            else if (value[1] === "Credit Card") {
                cipher.type = CipherType.Card;
                cipher.card.number = this.getValueOrDefault(this.splitValueRetainingLastPart(value[4]));
                const [month, year] = this.getValueOrDefault(this.splitValueRetainingLastPart(value[5])).split("/");
                cipher.card.expMonth = month.trim();
                cipher.card.expYear = year.trim();
                const securityCodeRegex = RegExp("^Security Code\\|\\d*\\|");
                const securityCodeEntry = value.find((entry) => securityCodeRegex.test(entry));
                cipher.card.code = this.getValueOrDefault(this.splitValueRetainingLastPart(securityCodeEntry));
                const cardNameRegex = RegExp("^Name on Card\\|\\d*\\|");
                const nameOnCardEntry = value.find((entry) => entry.match(cardNameRegex));
                cipher.card.cardholderName = this.getValueOrDefault(this.splitValueRetainingLastPart(nameOnCardEntry));
                cipher.card.brand = this.getValueOrDefault(this.splitValueRetainingLastPart(value[9]), "");
                const noteRegex = RegExp("\\|\\d*\\|");
                const rawNotes = value
                    .slice(2)
                    .filter((entry) => !this.isNullOrWhitespace(entry) && !noteRegex.test(entry));
                const noteIndexes = [8, 10, 11];
                const indexedNotes = noteIndexes
                    .filter((idx) => value[idx] && noteRegex.test(value[idx]))
                    .map((idx) => value[idx])
                    .map((val) => {
                    const key = val.split("|")[0];
                    const value = this.getValueOrDefault(this.splitValueRetainingLastPart(val), "");
                    return `${key}: ${value}`;
                });
                cipher.notes = [...rawNotes, ...indexedNotes].join("\n");
            }
            else if (value.length > 3) {
                cipher.type = CipherType.SecureNote;
                cipher.secureNote = new SecureNoteView();
                cipher.secureNote.type = SecureNoteType.Generic;
                for (let i = 3; i < value.length; i++) {
                    if (!this.isNullOrWhitespace(value[i])) {
                        cipher.notes += value[i] + "\n";
                    }
                }
            }
            if (!this.isNullOrWhitespace(value[1]) &&
                cipher.type !== CipherType.Login &&
                cipher.type !== CipherType.Card) {
                cipher.name = value[1] + ": " + cipher.name;
            }
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
    // mSecure returns values separated by "|" where after the second separator is the value
    // like "Password|8|myPassword", we want to keep the "myPassword" but also ensure that if
    // the value contains any "|" it works fine
    splitValueRetainingLastPart(value) {
        return value && value.split("|").slice(0, 2).concat(value.split("|").slice(2).join("|")).pop();
    }
}

;// ../../libs/importer/src/importers/myki-csv-importer.ts






const mappedBaseColumns = ["nickname", "additionalInfo"];
const _mappedUserAccountColumns = new Set(mappedBaseColumns.concat(["url", "username", "password", "twofaSecret"]));
const _mappedCreditCardColumns = new Set(mappedBaseColumns.concat(["cardNumber", "cardName", "exp_month", "exp_year", "cvv"]));
const _mappedIdentityColumns = new Set(mappedBaseColumns.concat([
    "title",
    "firstName",
    "middleName",
    "lastName",
    "email",
    "firstAddressLine",
    "secondAddressLine",
    "city",
    "country",
    "zipCode",
]));
const _mappedIdCardColumns = new Set(mappedBaseColumns.concat(["idName", "idNumber", "idCountry"]));
const _mappedTwoFaColumns = new Set(mappedBaseColumns.concat(["authToken"]));
const _mappedUserNoteColumns = new Set(mappedBaseColumns.concat(["content"]));
class MykiCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(value.nickname, "--");
            cipher.notes = this.getValueOrDefault(value.additionalInfo, "").trimEnd();
            if (value.url !== undefined) {
                // Accounts
                cipher.login.uris = this.makeUriArray(value.url);
                cipher.login.username = this.getValueOrDefault(value.username);
                cipher.login.password = this.getValueOrDefault(value.password);
                cipher.login.totp = this.getValueOrDefault(value.twofaSecret);
                this.importUnmappedFields(cipher, value, _mappedUserAccountColumns);
            }
            else if (value.authToken !== undefined) {
                // TwoFA
                cipher.login.totp = this.getValueOrDefault(value.authToken);
                this.importUnmappedFields(cipher, value, _mappedTwoFaColumns);
            }
            else if (value.cardNumber !== undefined) {
                // Cards
                cipher.card = new CardView();
                cipher.type = CipherType.Card;
                cipher.card.cardholderName = this.getValueOrDefault(value.cardName);
                cipher.card.number = this.getValueOrDefault(value.cardNumber);
                cipher.card.brand = CardView.getCardBrandByPatterns(cipher.card.number);
                cipher.card.expMonth = this.getValueOrDefault(value.exp_month);
                cipher.card.expYear = this.getValueOrDefault(value.exp_year);
                cipher.card.code = this.getValueOrDefault(value.cvv);
                this.importUnmappedFields(cipher, value, _mappedCreditCardColumns);
            }
            else if (value.firstName !== undefined) {
                // Identities
                cipher.identity = new IdentityView();
                cipher.type = CipherType.Identity;
                cipher.identity.title = this.getValueOrDefault(value.title);
                cipher.identity.firstName = this.getValueOrDefault(value.firstName);
                cipher.identity.middleName = this.getValueOrDefault(value.middleName);
                cipher.identity.lastName = this.getValueOrDefault(value.lastName);
                cipher.identity.phone = this.getValueOrDefault(value.number);
                cipher.identity.email = this.getValueOrDefault(value.email);
                cipher.identity.address1 = this.getValueOrDefault(value.firstAddressLine);
                cipher.identity.address2 = this.getValueOrDefault(value.secondAddressLine);
                cipher.identity.city = this.getValueOrDefault(value.city);
                cipher.identity.country = this.getValueOrDefault(value.country);
                cipher.identity.postalCode = this.getValueOrDefault(value.zipCode);
                this.importUnmappedFields(cipher, value, _mappedIdentityColumns);
            }
            else if (value.idType !== undefined) {
                // IdCards
                cipher.identity = new IdentityView();
                cipher.type = CipherType.Identity;
                this.processFullName(cipher, value.idName);
                cipher.identity.country = this.getValueOrDefault(value.idCountry);
                switch (value.idType) {
                    // case "Driver's License":
                    // case "ID Card":
                    // case "Outdoor License":
                    // case "Software License":
                    // case "Tax Number":
                    // case "Bank Account":
                    // case "Insurance Card":
                    // case "Health Card":
                    // case "Membership":
                    // case "Database":
                    // case "Reward Program":
                    // case "Tour Visa":
                    case "Passport":
                        cipher.identity.passportNumber = value.idNumber;
                        break;
                    case "Social Security":
                        cipher.identity.ssn = value.idNumber;
                        break;
                    default:
                        cipher.identity.licenseNumber = value.idNumber;
                        break;
                }
                this.importUnmappedFields(cipher, value, _mappedIdCardColumns);
            }
            else if (value.content !== undefined) {
                // Notes
                cipher.secureNote = new SecureNoteView();
                cipher.type = CipherType.SecureNote;
                cipher.secureNote.type = SecureNoteType.Generic;
                cipher.notes = this.getValueOrDefault(value.content, "").trimEnd();
                this.importUnmappedFields(cipher, value, _mappedUserNoteColumns);
            }
            else {
                return;
            }
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
    importUnmappedFields(cipher, row, mappedValues) {
        const unmappedFields = Object.keys(row).filter((x) => !mappedValues.has(x));
        unmappedFields.forEach((key) => {
            const item = row;
            this.processKvp(cipher, key, item[key]);
        });
    }
}

;// ../../libs/importer/src/importers/netwrix/netwrix-passwordsecure-csv-importer.ts


const _mappedColumns = new Set([
    "Organisationseinheit",
    "Informationen",
    "Beschreibung",
    "Benutzername",
    "Passwort",
    "Internetseite",
    "One-Time Passwort",
]);
/**
 * Importer for Netwrix Password Secure CSV files.
 * @see https://www.netwrix.com/enterprise_password_management_software.html
 */
class NetwrixPasswordSecureCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((row) => {
            this.processFolder(result, row.Organisationseinheit);
            const cipher = this.initLoginCipher();
            const notes = this.getValueOrDefault(row.Informationen);
            if (notes) {
                cipher.notes = notes.trimEnd();
            }
            cipher.name = this.getValueOrDefault(row.Beschreibung, "--");
            cipher.login.username = this.getValueOrDefault(row.Benutzername);
            cipher.login.password = this.getValueOrDefault(row.Passwort);
            cipher.login.uris = this.makeUriArray(row.Internetseite);
            cipher.login.totp = this.getValueOrDefault(row["One-Time Passwort"]);
            this.importUnmappedFields(cipher, row, _mappedColumns);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
    importUnmappedFields(cipher, row, mappedValues) {
        const unmappedFields = Object.keys(row).filter((x) => !mappedValues.has(x));
        unmappedFields.forEach((key) => {
            const item = row;
            this.processKvp(cipher, key, item[key]);
        });
    }
}

;// ../../libs/importer/src/importers/netwrix/index.ts


;// ../../libs/importer/src/importers/nordpass-csv-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore






class NordPassCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((record) => {
            const recordType = this.evaluateType(record);
            if (recordType === undefined) {
                return;
            }
            this.processFolder(result, record.folder);
            const cipher = new CipherView();
            cipher.name = this.getValueOrDefault(record.name, "--");
            cipher.notes = this.getValueOrDefault(record.note);
            if (record.custom_fields) {
                const customFieldsParsed = JSON.parse(record.custom_fields);
                if (customFieldsParsed && customFieldsParsed.length > 0) {
                    customFieldsParsed.forEach((field) => {
                        let fieldType = FieldType.Text;
                        if (field.type == "hidden") {
                            fieldType = FieldType.Hidden;
                        }
                        this.processKvp(cipher, field.label, field.value, fieldType);
                    });
                }
            }
            switch (recordType) {
                case CipherType.Login:
                    cipher.type = CipherType.Login;
                    cipher.login = new LoginView();
                    cipher.login.username = this.getValueOrDefault(record.username);
                    cipher.login.password = this.getValueOrDefault(record.password);
                    if (record.additional_urls) {
                        const additionalUrlsParsed = JSON.parse(record.additional_urls);
                        const uris = [record.url, ...additionalUrlsParsed];
                        cipher.login.uris = this.makeUriArray(uris);
                    }
                    else {
                        cipher.login.uris = this.makeUriArray(record.url);
                    }
                    break;
                case CipherType.Card:
                    cipher.type = CipherType.Card;
                    cipher.card.cardholderName = this.getValueOrDefault(record.cardholdername);
                    cipher.card.number = this.getValueOrDefault(record.cardnumber);
                    cipher.card.code = this.getValueOrDefault(record.cvc);
                    cipher.card.brand = CardView.getCardBrandByPatterns(cipher.card.number);
                    this.setCardExpiration(cipher, record.expirydate);
                    break;
                case CipherType.Identity:
                    cipher.type = CipherType.Identity;
                    this.processFullName(cipher, this.getValueOrDefault(record.full_name));
                    cipher.identity.address1 = this.getValueOrDefault(record.address1);
                    cipher.identity.address2 = this.getValueOrDefault(record.address2);
                    cipher.identity.city = this.getValueOrDefault(record.city);
                    cipher.identity.state = this.getValueOrDefault(record.state);
                    cipher.identity.postalCode = this.getValueOrDefault(record.zipcode);
                    cipher.identity.country = this.getValueOrDefault(record.country);
                    if (cipher.identity.country != null) {
                        cipher.identity.country = cipher.identity.country.toUpperCase();
                    }
                    cipher.identity.email = this.getValueOrDefault(record.email);
                    cipher.identity.phone = this.getValueOrDefault(record.phone_number);
                    break;
                case CipherType.SecureNote:
                    cipher.type = CipherType.SecureNote;
                    cipher.secureNote.type = SecureNoteType.Generic;
                    break;
                default:
                    break;
            }
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
    evaluateType(record) {
        switch (record.type) {
            case "password":
                return CipherType.Login;
            case "credit_card":
                return CipherType.Card;
            case "note":
                return CipherType.SecureNote;
            case "identity":
                return CipherType.Identity;
        }
        return undefined;
    }
}

;// ../../libs/importer/src/importers/onepassword/onepassword-1pif-importer.ts







class OnePassword1PifImporter extends BaseImporter {
    constructor() {
        super(...arguments);
        this.result = new ImportResult();
    }
    parse(data) {
        data.split(this.newLineRegex).forEach((line) => {
            if (this.isNullOrWhitespace(line) || line[0] !== "{") {
                return;
            }
            const item = JSON.parse(line);
            if (item.trashed === true) {
                return;
            }
            const cipher = this.initLoginCipher();
            if (this.isNullOrWhitespace(item.hmac)) {
                this.processStandardItem(item, cipher);
            }
            else {
                this.processWinOpVaultItem(item, cipher);
            }
            this.convertToNoteIfNeeded(cipher);
            this.cleanupCipher(cipher);
            this.result.ciphers.push(cipher);
        });
        this.result.success = true;
        return Promise.resolve(this.result);
    }
    processWinOpVaultItem(item, cipher) {
        if (item.overview != null) {
            cipher.name = this.getValueOrDefault(item.overview.title);
            if (item.overview.URLs != null) {
                const urls = [];
                item.overview.URLs.forEach((url) => {
                    if (!this.isNullOrWhitespace(url.u)) {
                        urls.push(url.u);
                    }
                });
                cipher.login.uris = this.makeUriArray(urls);
            }
        }
        if (item.details != null) {
            if (item.details.passwordHistory != null) {
                this.parsePasswordHistory(item.details.passwordHistory, cipher);
            }
            if (!this.isNullOrWhitespace(item.details.ccnum) ||
                !this.isNullOrWhitespace(item.details.cvv)) {
                cipher.type = CipherType.Card;
                cipher.card = new CardView();
            }
            else if (!this.isNullOrWhitespace(item.details.firstname) ||
                !this.isNullOrWhitespace(item.details.address1)) {
                cipher.type = CipherType.Identity;
                cipher.identity = new IdentityView();
            }
            if (cipher.type === CipherType.Login && !this.isNullOrWhitespace(item.details.password)) {
                cipher.login.password = item.details.password;
            }
            if (!this.isNullOrWhitespace(item.details.notesPlain)) {
                cipher.notes = item.details.notesPlain.split(this.newLineRegex).join("\n") + "\n";
            }
            if (item.details.fields != null) {
                this.parseFields(item.details.fields, cipher, "designation", "value", "name");
            }
            if (item.details.sections != null) {
                item.details.sections.forEach((section) => {
                    if (section.fields != null) {
                        this.parseFields(section.fields, cipher, "n", "v", "t");
                    }
                });
            }
        }
    }
    processStandardItem(item, cipher) {
        cipher.favorite = item.openContents && item.openContents.faveIndex ? true : false;
        cipher.name = this.getValueOrDefault(item.title);
        if (item.typeName === "securenotes.SecureNote") {
            cipher.type = CipherType.SecureNote;
            cipher.secureNote = new SecureNoteView();
            cipher.secureNote.type = SecureNoteType.Generic;
        }
        else if (item.typeName === "wallet.financial.CreditCard") {
            cipher.type = CipherType.Card;
            cipher.card = new CardView();
        }
        else if (item.typeName === "identities.Identity") {
            cipher.type = CipherType.Identity;
            cipher.identity = new IdentityView();
        }
        else {
            cipher.login.uris = this.makeUriArray(item.location);
        }
        if (item.secureContents != null) {
            if (item.secureContents.passwordHistory != null) {
                this.parsePasswordHistory(item.secureContents.passwordHistory, cipher);
            }
            if (!this.isNullOrWhitespace(item.secureContents.notesPlain)) {
                cipher.notes = item.secureContents.notesPlain.split(this.newLineRegex).join("\n") + "\n";
            }
            if (cipher.type === CipherType.Login) {
                if (!this.isNullOrWhitespace(item.secureContents.password)) {
                    cipher.login.password = item.secureContents.password;
                }
                if (item.secureContents.URLs != null) {
                    const urls = [];
                    item.secureContents.URLs.forEach((u) => {
                        if (!this.isNullOrWhitespace(u.url)) {
                            urls.push(u.url);
                        }
                    });
                    if (urls.length > 0) {
                        cipher.login.uris = this.makeUriArray(urls);
                    }
                }
            }
            if (item.secureContents.fields != null) {
                this.parseFields(item.secureContents.fields, cipher, "designation", "value", "name");
            }
            if (item.secureContents.sections != null) {
                item.secureContents.sections.forEach((section) => {
                    if (section.fields != null) {
                        this.parseFields(section.fields, cipher, "n", "v", "t");
                    }
                });
            }
        }
    }
    parsePasswordHistory(items, cipher) {
        const maxSize = items.length > 5 ? 5 : items.length;
        cipher.passwordHistory = items
            .filter((h) => !this.isNullOrWhitespace(h.value) && h.time != null)
            .sort((a, b) => b.time - a.time)
            .slice(0, maxSize)
            .map((h) => {
            const ph = new PasswordHistoryView();
            ph.password = h.value;
            ph.lastUsedDate = new Date(("" + h.time).length >= 13 ? h.time : h.time * 1000);
            return ph;
        });
    }
    parseFields(fields, cipher, designationKey, valueKey, nameKey) {
        fields.forEach((field) => {
            if (field[valueKey] == null || field[valueKey].toString().trim() === "") {
                return;
            }
            // TODO: when date FieldType exists, store this as a date field type instead of formatted Text if k is 'date'
            const fieldValue = field.k === "date"
                ? new Date(field[valueKey] * 1000).toUTCString()
                : field[valueKey].toString();
            const fieldDesignation = field[designationKey] != null ? field[designationKey].toString() : null;
            if (cipher.type === CipherType.Login) {
                if (this.isNullOrWhitespace(cipher.login.username) && fieldDesignation === "username") {
                    cipher.login.username = fieldValue;
                    return;
                }
                else if (this.isNullOrWhitespace(cipher.login.password) &&
                    fieldDesignation === "password") {
                    cipher.login.password = fieldValue;
                    return;
                }
                else if (this.isNullOrWhitespace(cipher.login.totp) &&
                    fieldDesignation != null &&
                    fieldDesignation.startsWith("TOTP_")) {
                    cipher.login.totp = fieldValue;
                    return;
                }
            }
            else if (cipher.type === CipherType.Card) {
                if (this.isNullOrWhitespace(cipher.card.number) && fieldDesignation === "ccnum") {
                    cipher.card.number = fieldValue;
                    cipher.card.brand = CardView.getCardBrandByPatterns(cipher.card.number);
                    return;
                }
                else if (this.isNullOrWhitespace(cipher.card.code) && fieldDesignation === "cvv") {
                    cipher.card.code = fieldValue;
                    return;
                }
                else if (this.isNullOrWhitespace(cipher.card.cardholderName) &&
                    fieldDesignation === "cardholder") {
                    cipher.card.cardholderName = fieldValue;
                    return;
                }
                else if (this.isNullOrWhitespace(cipher.card.expiration) &&
                    fieldDesignation === "expiry" &&
                    fieldValue.length === 6) {
                    cipher.card.expMonth = fieldValue.substr(4, 2);
                    if (cipher.card.expMonth[0] === "0") {
                        cipher.card.expMonth = cipher.card.expMonth.substr(1, 1);
                    }
                    cipher.card.expYear = fieldValue.substr(0, 4);
                    return;
                }
                else if (fieldDesignation === "type") {
                    // Skip since brand was determined from number above
                    return;
                }
            }
            else if (cipher.type === CipherType.Identity) {
                const identity = cipher.identity;
                if (this.isNullOrWhitespace(identity.firstName) && fieldDesignation === "firstname") {
                    identity.firstName = fieldValue;
                    return;
                }
                else if (this.isNullOrWhitespace(identity.lastName) && fieldDesignation === "lastname") {
                    identity.lastName = fieldValue;
                    return;
                }
                else if (this.isNullOrWhitespace(identity.middleName) && fieldDesignation === "initial") {
                    identity.middleName = fieldValue;
                    return;
                }
                else if (this.isNullOrWhitespace(identity.phone) && fieldDesignation === "defphone") {
                    identity.phone = fieldValue;
                    return;
                }
                else if (this.isNullOrWhitespace(identity.company) && fieldDesignation === "company") {
                    identity.company = fieldValue;
                    return;
                }
                else if (this.isNullOrWhitespace(identity.email) && fieldDesignation === "email") {
                    identity.email = fieldValue;
                    return;
                }
                else if (this.isNullOrWhitespace(identity.username) && fieldDesignation === "username") {
                    identity.username = fieldValue;
                    return;
                }
                else if (fieldDesignation === "address") {
                    // fieldValue is an object casted into a string, so access the plain value instead
                    const { street, city, country, zip } = field[valueKey];
                    identity.address1 = this.getValueOrDefault(street);
                    identity.city = this.getValueOrDefault(city);
                    if (!this.isNullOrWhitespace(country)) {
                        identity.country = country.toUpperCase();
                    }
                    identity.postalCode = this.getValueOrDefault(zip);
                    return;
                }
            }
            const fieldName = this.isNullOrWhitespace(field[nameKey]) ? "no_name" : field[nameKey];
            if (fieldName === "password" &&
                cipher.passwordHistory != null &&
                cipher.passwordHistory.some((h) => h.password === fieldValue)) {
                return;
            }
            const fieldType = field.k === "concealed" ? FieldType.Hidden : FieldType.Text;
            this.processKvp(cipher, fieldName, fieldValue, fieldType);
        });
    }
}

;// ../../libs/importer/src/importers/onepassword/types/onepassword-1pux-importer-types.ts
/**
 * Represents the different types of items that can be stored in 1Password.
 */
const Category = Object.freeze({
    Login: "001",
    CreditCard: "002",
    SecureNote: "003",
    Identity: "004",
    Password: "005",
    Document: "006",
    SoftwareLicense: "100",
    BankAccount: "101",
    Database: "102",
    DriversLicense: "103",
    OutdoorLicense: "104",
    Membership: "105",
    Passport: "106",
    RewardsProgram: "107",
    SocialSecurityNumber: "108",
    WirelessRouter: "109",
    Server: "110",
    EmailAccount: "111",
    API_Credential: "112",
    MedicalRecord: "113",
    SSH_Key: "114",
});
/**
 * Represents 1Password login field types that can be stored in login items.
 */
const LoginFieldType = Object.freeze({
    TextOrHtml: "T",
    EmailAddress: "E",
    URL: "U",
    Number: "N",
    Password: "P",
    TextArea: "A",
    PhoneNumber: "TEL",
    CheckBox: "C",
});

;// ../../libs/importer/src/importers/onepassword/onepassword-1pux-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore












class OnePassword1PuxImporter extends BaseImporter {
    constructor() {
        super(...arguments);
        this.result = new ImportResult();
    }
    parse(data) {
        const exportData = JSON.parse(data);
        const account = exportData.accounts[0];
        // TODO Add handling of multiple vaults
        // const personalVaults = account.vaults[0].filter((v) => v.attrs.type === VaultAttributeTypeEnum.Personal);
        account.vaults.forEach((vault) => {
            vault.items.forEach((item) => {
                if (item.state === "archived") {
                    return;
                }
                const cipher = this.initLoginCipher();
                const category = item.categoryUuid;
                switch (category) {
                    case Category.Login:
                    case Category.Database:
                    case Category.Password:
                    case Category.WirelessRouter:
                    case Category.Server:
                    case Category.API_Credential:
                        cipher.type = CipherType.Login;
                        cipher.login = new LoginView();
                        break;
                    case Category.CreditCard:
                    case Category.BankAccount:
                        cipher.type = CipherType.Card;
                        cipher.card = new CardView();
                        break;
                    case Category.SecureNote:
                    case Category.SoftwareLicense:
                    case Category.EmailAccount:
                    case Category.MedicalRecord:
                        // case CategoryEnum.Document:
                        cipher.type = CipherType.SecureNote;
                        cipher.secureNote = new SecureNoteView();
                        cipher.secureNote.type = SecureNoteType.Generic;
                        break;
                    case Category.Identity:
                    case Category.DriversLicense:
                    case Category.OutdoorLicense:
                    case Category.Membership:
                    case Category.Passport:
                    case Category.RewardsProgram:
                    case Category.SocialSecurityNumber:
                        cipher.type = CipherType.Identity;
                        cipher.identity = new IdentityView();
                        break;
                    case Category.SSH_Key:
                        cipher.type = CipherType.SshKey;
                        cipher.sshKey = new SshKeyView();
                        break;
                    default:
                        break;
                }
                cipher.favorite = item.favIndex === 1 ? true : false;
                this.processOverview(item.overview, cipher);
                this.processLoginFields(item, cipher);
                this.processDetails(category, item.details, cipher);
                this.parsePasswordHistory(item.details.passwordHistory, cipher);
                this.processSections(category, item.details.sections, cipher);
                if (!this.isNullOrWhitespace(item.details.notesPlain)) {
                    cipher.notes = item.details.notesPlain.split(this.newLineRegex).join("\n").trimEnd();
                }
                this.convertToNoteIfNeeded(cipher);
                this.cleanupCipher(cipher);
                this.result.ciphers.push(cipher);
            });
        });
        if (this.organization) {
            this.moveFoldersToCollections(this.result);
        }
        this.result.success = true;
        return Promise.resolve(this.result);
    }
    processOverview(overview, cipher) {
        if (overview == null) {
            return;
        }
        cipher.name = this.getValueOrDefault(overview.title);
        if (overview.urls != null) {
            const urls = [];
            overview.urls.forEach((url) => {
                if (!this.isNullOrWhitespace(url.url)) {
                    urls.push(url.url);
                }
            });
            cipher.login.uris = this.makeUriArray(urls);
        }
        if (overview.tags != null && overview.tags.length > 0) {
            const folderName = this.capitalize(overview.tags[0]);
            this.processFolder(this.result, folderName);
        }
    }
    capitalize(inputString) {
        return inputString.trim().replace(/\w\S*/g, (w) => w.replace(/^\w/, (c) => c.toUpperCase()));
    }
    processLoginFields(item, cipher) {
        if (item.details == null) {
            return;
        }
        if (item.details.loginFields == null || item.details.loginFields.length === 0) {
            return;
        }
        item.details.loginFields.forEach((loginField) => {
            if (loginField.designation === "username" && loginField.value !== "") {
                cipher.type = CipherType.Login;
                cipher.login.username = loginField.value;
                return;
            }
            if (loginField.designation === "password" && loginField.value !== "") {
                cipher.type = CipherType.Login;
                cipher.login.password = loginField.value;
                return;
            }
            let fieldValue = loginField.value;
            let fieldType = FieldType.Text;
            switch (loginField.fieldType) {
                case LoginFieldType.Password:
                    fieldType = FieldType.Hidden;
                    break;
                case LoginFieldType.CheckBox:
                    fieldValue = loginField.value !== "" ? "true" : "false";
                    fieldType = FieldType.Boolean;
                    break;
                default:
                    break;
            }
            this.processKvp(cipher, loginField.name, fieldValue, fieldType);
        });
    }
    processDetails(category, details, cipher) {
        if (category !== Category.Password) {
            return;
        }
        if (details == null) {
            return;
        }
        cipher.login.password = details.password;
    }
    processSections(category, sections, cipher) {
        if (sections == null || sections.length === 0) {
            return;
        }
        sections.forEach((section) => {
            if (section.fields == null) {
                return;
            }
            this.parseSectionFields(category, section.fields, cipher, section.title);
        });
    }
    parseSectionFields(category, fields, cipher, sectionTitle) {
        fields.forEach((field) => {
            const valueKey = Object.keys(field.value)[0];
            const anyField = field;
            if (anyField.value == null ||
                anyField.value[valueKey] == null ||
                anyField.value[valueKey] === "") {
                return;
            }
            const fieldName = this.getFieldName(field.title, sectionTitle);
            const fieldValue = this.extractValue(field.value, valueKey);
            if (cipher.type === CipherType.Login) {
                if (this.fillLogin(field, fieldValue, cipher)) {
                    return;
                }
                switch (category) {
                    case Category.Login:
                    case Category.Database:
                    case Category.EmailAccount:
                    case Category.WirelessRouter:
                        break;
                    case Category.Server:
                        if (this.isNullOrWhitespace(cipher.login.uri) && field.id === "url") {
                            cipher.login.uris = this.makeUriArray(fieldValue);
                            return;
                        }
                        break;
                    case Category.API_Credential:
                        if (this.fillApiCredentials(field, fieldValue, cipher)) {
                            return;
                        }
                        break;
                    default:
                        break;
                }
            }
            else if (cipher.type === CipherType.Card) {
                if (this.fillCreditCard(field, fieldValue, cipher)) {
                    return;
                }
                if (category === Category.BankAccount) {
                    if (this.fillBankAccount(field, fieldValue, cipher)) {
                        return;
                    }
                }
            }
            else if (cipher.type === CipherType.Identity) {
                if (this.fillIdentity(field, fieldValue, cipher, valueKey)) {
                    return;
                }
                if (valueKey === "address") {
                    // fieldValue is an object casted into a string, so access the plain value instead
                    const { street, city, country, zip, state } = field.value.address;
                    cipher.identity.address1 = this.getValueOrDefault(street);
                    cipher.identity.city = this.getValueOrDefault(city);
                    if (!this.isNullOrWhitespace(country)) {
                        cipher.identity.country = country.toUpperCase();
                    }
                    cipher.identity.postalCode = this.getValueOrDefault(zip);
                    cipher.identity.state = this.getValueOrDefault(state);
                    return;
                }
                switch (category) {
                    case Category.Identity:
                        break;
                    case Category.DriversLicense:
                        if (this.fillDriversLicense(field, fieldValue, cipher)) {
                            return;
                        }
                        break;
                    case Category.OutdoorLicense:
                        if (this.fillOutdoorLicense(field, fieldValue, cipher)) {
                            return;
                        }
                        break;
                    case Category.Membership:
                        if (this.fillMembership(field, fieldValue, cipher)) {
                            return;
                        }
                        break;
                    case Category.Passport:
                        if (this.fillPassport(field, fieldValue, cipher)) {
                            return;
                        }
                        break;
                    case Category.RewardsProgram:
                        if (this.fillRewardsProgram(field, fieldValue, cipher)) {
                            return;
                        }
                        break;
                    case Category.SocialSecurityNumber:
                        if (this.fillSSN(field, fieldValue, cipher)) {
                            return;
                        }
                        break;
                    default:
                        break;
                }
            }
            else if (cipher.type === CipherType.SshKey) {
                if (valueKey === "sshKey") {
                    // Use sshKey.metadata.privateKey instead of the sshKey.privateKey field.
                    // The sshKey.privateKey field doesn't have a consistent format for every item.
                    const { privateKey } = field.value.sshKey.metadata;
                    // Convert SSH key from PKCS#8 (1Password format) to OpenSSH format using SDK
                    // Note: 1Password does not store password-protected SSH keys, so no password handling needed for now
                    const parsedKey = (0,bitwarden_wasm_internal_bg/* import_ssh_key */.bnN)(privateKey);
                    cipher.sshKey.privateKey = parsedKey.privateKey;
                    cipher.sshKey.publicKey = parsedKey.publicKey;
                    cipher.sshKey.keyFingerprint = parsedKey.fingerprint;
                    return;
                }
            }
            if (valueKey === "email") {
                // fieldValue is an object casted into a string, so access the plain value instead
                const { email_address, provider } = field.value.email;
                this.processKvp(cipher, fieldName, email_address, FieldType.Text);
                this.processKvp(cipher, "provider", provider, FieldType.Text);
                return;
            }
            // Do not include a password field if it's already in the history
            if (field.title === "password" &&
                cipher.passwordHistory != null &&
                cipher.passwordHistory.some((h) => h.password === fieldValue)) {
                return;
            }
            // TODO ?? If one of the fields is marked as guarded, then activate Password-Reprompt for the entire item
            if (field.guarded && cipher.reprompt === CipherRepromptType.None) {
                cipher.reprompt = CipherRepromptType.Password;
            }
            const fieldType = valueKey === "concealed" ? FieldType.Hidden : FieldType.Text;
            this.processKvp(cipher, fieldName, fieldValue, fieldType);
        });
    }
    // Use the title if available. If not use the sectionTitle if available.
    // Default to an empty string in all other cases.
    getFieldName(title, sectionTitle) {
        if (!this.isNullOrWhitespace(title)) {
            return title;
        }
        if (!this.isNullOrWhitespace(sectionTitle)) {
            return sectionTitle;
        }
        return "";
    }
    extractValue(value, valueKey) {
        if (valueKey === "date") {
            return new Date(value.date * 1000).toUTCString();
        }
        if (valueKey === "monthYear") {
            return value.monthYear.toString();
        }
        return value[valueKey];
    }
    fillLogin(field, fieldValue, cipher) {
        const fieldName = this.getFieldName(field.title);
        if (this.isNullOrWhitespace(cipher.login.username) && fieldName === "username") {
            cipher.login.username = fieldValue;
            return true;
        }
        if (this.isNullOrWhitespace(cipher.login.password) && fieldName === "password") {
            cipher.login.password = fieldValue;
            return true;
        }
        if (this.isNullOrWhitespace(cipher.login.totp) &&
            field.id != null &&
            field.id.startsWith("TOTP_")) {
            cipher.login.totp = fieldValue;
            return true;
        }
        return false;
    }
    fillApiCredentials(field, fieldValue, cipher) {
        const fieldName = this.getFieldName(field.title);
        if (this.isNullOrWhitespace(cipher.login.password) && fieldName === "credential") {
            cipher.login.password = fieldValue;
            return true;
        }
        if (this.isNullOrWhitespace(cipher.login.uri) && fieldName === "hostname") {
            cipher.login.uris = this.makeUriArray(fieldValue);
            return true;
        }
        return false;
    }
    fillCreditCard(field, fieldValue, cipher) {
        if (this.isNullOrWhitespace(cipher.card.number) && field.id === "ccnum") {
            cipher.card.number = fieldValue;
            cipher.card.brand = CardView.getCardBrandByPatterns(cipher.card.number);
            return true;
        }
        if (this.isNullOrWhitespace(cipher.card.code) && field.id === "cvv") {
            cipher.card.code = fieldValue;
            return true;
        }
        if (this.isNullOrWhitespace(cipher.card.cardholderName) && field.id === "cardholder") {
            cipher.card.cardholderName = fieldValue;
            return true;
        }
        if (this.isNullOrWhitespace(cipher.card.expiration) && field.id === "expiry") {
            const monthYear = fieldValue.toString().trim();
            cipher.card.expMonth = monthYear.substring(4, 6);
            if (cipher.card.expMonth[0] === "0") {
                cipher.card.expMonth = cipher.card.expMonth.substring(1, 2);
            }
            cipher.card.expYear = monthYear.substring(0, 4);
            return true;
        }
        if (field.id === "type") {
            // Skip since brand was determined from number above
            return true;
        }
        return false;
    }
    fillBankAccount(field, fieldValue, cipher) {
        if (this.isNullOrWhitespace(cipher.card.cardholderName) && field.id === "owner") {
            cipher.card.cardholderName = fieldValue;
            return true;
        }
        return false;
    }
    fillIdentity(field, fieldValue, cipher, valueKey) {
        if (this.isNullOrWhitespace(cipher.identity.firstName) && field.id === "firstname") {
            cipher.identity.firstName = fieldValue;
            return true;
        }
        if (this.isNullOrWhitespace(cipher.identity.lastName) && field.id === "lastname") {
            cipher.identity.lastName = fieldValue;
            return true;
        }
        if (this.isNullOrWhitespace(cipher.identity.middleName) && field.id === "initial") {
            cipher.identity.middleName = fieldValue;
            return true;
        }
        if (this.isNullOrWhitespace(cipher.identity.phone) && field.id === "defphone") {
            cipher.identity.phone = fieldValue;
            return true;
        }
        if (this.isNullOrWhitespace(cipher.identity.company) && field.id === "company") {
            cipher.identity.company = fieldValue;
            return true;
        }
        if (this.isNullOrWhitespace(cipher.identity.email)) {
            if (valueKey === "email") {
                const { email_address, provider } = field.value.email;
                cipher.identity.email = this.getValueOrDefault(email_address);
                this.processKvp(cipher, "provider", provider, FieldType.Text);
                return true;
            }
            if (field.id === "email") {
                cipher.identity.email = fieldValue;
                return true;
            }
        }
        if (this.isNullOrWhitespace(cipher.identity.username) && field.id === "username") {
            cipher.identity.username = fieldValue;
            return true;
        }
        return false;
    }
    fillDriversLicense(field, fieldValue, cipher) {
        if (this.isNullOrWhitespace(cipher.identity.firstName) && field.id === "fullname") {
            this.processFullName(cipher, fieldValue);
            return true;
        }
        if (this.isNullOrWhitespace(cipher.identity.address1) && field.id === "address") {
            cipher.identity.address1 = fieldValue;
            return true;
        }
        // TODO ISO code
        if (this.isNullOrWhitespace(cipher.identity.country) && field.id === "country") {
            cipher.identity.country = fieldValue;
            return true;
        }
        if (this.isNullOrWhitespace(cipher.identity.state) && field.id === "state") {
            cipher.identity.state = fieldValue;
            return true;
        }
        if (this.isNullOrWhitespace(cipher.identity.licenseNumber) && field.id === "number") {
            cipher.identity.licenseNumber = fieldValue;
            return true;
        }
        return false;
    }
    fillOutdoorLicense(field, fieldValue, cipher) {
        if (this.isNullOrWhitespace(cipher.identity.firstName) && field.id === "name") {
            this.processFullName(cipher, fieldValue);
            return true;
        }
        // TODO ISO code
        if (this.isNullOrWhitespace(cipher.identity.country) && field.id === "country") {
            cipher.identity.country = fieldValue;
            return true;
        }
        if (this.isNullOrWhitespace(cipher.identity.state) && field.id === "state") {
            cipher.identity.state = fieldValue;
            return true;
        }
        return false;
    }
    fillMembership(field, fieldValue, cipher) {
        if (this.isNullOrWhitespace(cipher.identity.firstName) && field.id === "member_name") {
            this.processFullName(cipher, fieldValue);
            return true;
        }
        if (this.isNullOrWhitespace(cipher.identity.company) && field.id === "org_name") {
            cipher.identity.company = fieldValue;
            return true;
        }
        if (this.isNullOrWhitespace(cipher.identity.phone) && field.id === "phone") {
            cipher.identity.phone = fieldValue;
            return true;
        }
        return false;
    }
    fillPassport(field, fieldValue, cipher) {
        if (this.isNullOrWhitespace(cipher.identity.firstName) && field.id === "fullname") {
            this.processFullName(cipher, fieldValue);
            return true;
        }
        // TODO Iso
        if (this.isNullOrWhitespace(cipher.identity.country) && field.id === "issuing_country") {
            cipher.identity.country = fieldValue;
            return true;
        }
        if (this.isNullOrWhitespace(cipher.identity.passportNumber) && field.id === "number") {
            cipher.identity.passportNumber = fieldValue;
            return true;
        }
        return false;
    }
    fillRewardsProgram(field, fieldValue, cipher) {
        if (this.isNullOrWhitespace(cipher.identity.firstName) && field.id === "member_name") {
            this.processFullName(cipher, fieldValue);
            return true;
        }
        if (this.isNullOrWhitespace(cipher.identity.company) && field.id === "company_name") {
            cipher.identity.company = fieldValue;
            return true;
        }
        return false;
    }
    fillSSN(field, fieldValue, cipher) {
        if (this.isNullOrWhitespace(cipher.identity.firstName) && field.id === "name") {
            this.processFullName(cipher, fieldValue);
            return true;
        }
        if (this.isNullOrWhitespace(cipher.identity.ssn) && field.id === "number") {
            cipher.identity.ssn = fieldValue;
            return true;
        }
        return false;
    }
    parsePasswordHistory(historyItems, cipher) {
        if (historyItems == null || historyItems.length === 0) {
            return;
        }
        const maxSize = historyItems.length > 5 ? 5 : historyItems.length;
        cipher.passwordHistory = historyItems
            .filter((h) => !this.isNullOrWhitespace(h.value) && h.time != null)
            .sort((a, b) => b.time - a.time)
            .slice(0, maxSize)
            .map((h) => {
            const ph = new PasswordHistoryView();
            ph.password = h.value;
            ph.lastUsedDate = new Date(("" + h.time).length >= 13 ? h.time : h.time * 1000);
            return ph;
        });
    }
}

;// ../../libs/importer/src/importers/onepassword/cipher-import-context.ts
class CipherImportContext {
    constructor(importRecord, property, cipher) {
        this.importRecord = importRecord;
        this.property = property;
        this.cipher = cipher;
        this.lowerProperty = property.toLowerCase();
    }
}

;// ../../libs/importer/src/importers/onepassword/onepassword-csv-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore





const IgnoredProperties = [
    "ainfo",
    "autosubmit",
    "notesplain",
    "ps",
    "scope",
    "tags",
    "title",
    "uuid",
    "notes",
];
class OnePasswordCsvImporter extends BaseImporter {
    constructor() {
        super(...arguments);
        this.loginPropertyParsers = [
            this.setLoginUsername,
            this.setLoginPassword,
            this.setLoginUris,
        ];
        this.creditCardPropertyParsers = [
            this.setCreditCardNumber,
            this.setCreditCardVerification,
            this.setCreditCardCardholderName,
            this.setCreditCardExpiry,
        ];
        this.identityPropertyParsers = [
            this.setIdentityFirstName,
            this.setIdentityInitial,
            this.setIdentityLastName,
            this.setIdentityUserName,
            this.setIdentityEmail,
            this.setIdentityPhone,
            this.setIdentityCompany,
        ];
    }
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true, {
            quoteChar: '"',
            escapeChar: "\\",
        });
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            if (this.isNullOrWhitespace(this.getProp(value, "title"))) {
                return;
            }
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(this.getProp(value, "title"), "--");
            this.setNotes(value, cipher);
            this.setCipherType(value, cipher);
            let altUsername = null;
            for (const property in value) {
                // eslint-disable-next-line
                if (!value.hasOwnProperty(property) || this.isNullOrWhitespace(value[property])) {
                    continue;
                }
                const context = new CipherImportContext(value, property, cipher);
                if (cipher.type === CipherType.Login && this.setKnownLoginValue(context)) {
                    continue;
                }
                else if (cipher.type === CipherType.Card && this.setKnownCreditCardValue(context)) {
                    continue;
                }
                else if (cipher.type === CipherType.Identity && this.setKnownIdentityValue(context)) {
                    continue;
                }
                altUsername = this.setUnknownValue(context, altUsername);
            }
            if (cipher.type === CipherType.Login &&
                !this.isNullOrWhitespace(altUsername) &&
                this.isNullOrWhitespace(cipher.login.username) &&
                altUsername.indexOf("://") === -1) {
                cipher.login.username = altUsername;
            }
            this.convertToNoteIfNeeded(cipher);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
    getProp(obj, name) {
        const lowerObj = Object.entries(obj).reduce((agg, entry) => {
            agg[entry[0].toLowerCase()] = entry[1];
            return agg;
        }, {});
        return lowerObj[name.toLowerCase()];
    }
    getPropByRegexp(obj, regexp) {
        const matchingKeys = Object.keys(obj).reduce((agg, key) => {
            if (key.match(regexp)) {
                agg.push(key);
            }
            return agg;
        }, []);
        if (matchingKeys.length === 0) {
            return null;
        }
        else {
            return obj[matchingKeys[0]];
        }
    }
    getPropIncluding(obj, name) {
        const includesMap = Object.keys(obj).reduce((agg, entry) => {
            if (entry.toLowerCase().includes(name.toLowerCase())) {
                agg.push(entry);
            }
            return agg;
        }, []);
        if (includesMap.length === 0) {
            return null;
        }
        else {
            return obj[includesMap[0]];
        }
    }
    setNotes(importRecord, cipher) {
        cipher.notes =
            this.getValueOrDefault(this.getProp(importRecord, "notesPlain"), "") +
                "\n" +
                this.getValueOrDefault(this.getProp(importRecord, "notes"), "") +
                "\n";
        cipher.notes.trim();
    }
    setKnownLoginValue(context) {
        return this.loginPropertyParsers.reduce((agg, func) => {
            if (!agg) {
                agg = func.bind(this)(context);
            }
            return agg;
        }, false);
    }
    setKnownCreditCardValue(context) {
        return this.creditCardPropertyParsers.reduce((agg, func) => {
            if (!agg) {
                agg = func.bind(this)(context);
            }
            return agg;
        }, false);
    }
    setKnownIdentityValue(context) {
        return this.identityPropertyParsers.reduce((agg, func) => {
            if (!agg) {
                agg = func.bind(this)(context);
            }
            return agg;
        }, false);
    }
    setUnknownValue(context, altUsername) {
        if (IgnoredProperties.indexOf(context.lowerProperty) === -1 &&
            !context.lowerProperty.startsWith("section:") &&
            !context.lowerProperty.startsWith("section ")) {
            if (altUsername == null && context.lowerProperty === "email") {
                return context.importRecord[context.property];
            }
            else if (context.lowerProperty === "created date" ||
                context.lowerProperty === "modified date") {
                const readableDate = new Date(parseInt(context.importRecord[context.property], 10) * 1000).toUTCString();
                this.processKvp(context.cipher, "1Password " + context.property, readableDate);
                return null;
            }
            if (context.lowerProperty.includes("password") ||
                context.lowerProperty.includes("key") ||
                context.lowerProperty.includes("secret")) {
                this.processKvp(context.cipher, context.property, context.importRecord[context.property], FieldType.Hidden);
            }
            else {
                this.processKvp(context.cipher, context.property, context.importRecord[context.property]);
            }
        }
        return null;
    }
    setIdentityFirstName(context) {
        if (this.isNullOrWhitespace(context.cipher.identity.firstName) &&
            context.lowerProperty.includes("first name")) {
            context.cipher.identity.firstName = context.importRecord[context.property];
            return true;
        }
        return false;
    }
    setIdentityInitial(context) {
        if (this.isNullOrWhitespace(context.cipher.identity.middleName) &&
            context.lowerProperty.includes("initial")) {
            context.cipher.identity.middleName = context.importRecord[context.property];
            return true;
        }
        return false;
    }
    setIdentityLastName(context) {
        if (this.isNullOrWhitespace(context.cipher.identity.lastName) &&
            context.lowerProperty.includes("last name")) {
            context.cipher.identity.lastName = context.importRecord[context.property];
            return true;
        }
        return false;
    }
    setIdentityUserName(context) {
        if (this.isNullOrWhitespace(context.cipher.identity.username) &&
            context.lowerProperty.includes("username")) {
            context.cipher.identity.username = context.importRecord[context.property];
            return true;
        }
        return false;
    }
    setIdentityCompany(context) {
        if (this.isNullOrWhitespace(context.cipher.identity.company) &&
            context.lowerProperty.includes("company")) {
            context.cipher.identity.company = context.importRecord[context.property];
            return true;
        }
        return false;
    }
    setIdentityPhone(context) {
        if (this.isNullOrWhitespace(context.cipher.identity.phone) &&
            context.lowerProperty.includes("default phone")) {
            context.cipher.identity.phone = context.importRecord[context.property];
            return true;
        }
        return false;
    }
    setIdentityEmail(context) {
        if (this.isNullOrWhitespace(context.cipher.identity.email) &&
            context.lowerProperty.includes("email")) {
            context.cipher.identity.email = context.importRecord[context.property];
            return true;
        }
        return false;
    }
    setCreditCardNumber(context) {
        if (this.isNullOrWhitespace(context.cipher.card.number) &&
            context.lowerProperty.includes("number")) {
            context.cipher.card.number = context.importRecord[context.property];
            context.cipher.card.brand = CardView.getCardBrandByPatterns(context.cipher.card.number);
            return true;
        }
        return false;
    }
    setCreditCardVerification(context) {
        if (this.isNullOrWhitespace(context.cipher.card.code) &&
            context.lowerProperty.includes("verification number")) {
            context.cipher.card.code = context.importRecord[context.property];
            return true;
        }
        return false;
    }
    setCreditCardCardholderName(context) {
        if (this.isNullOrWhitespace(context.cipher.card.cardholderName) &&
            context.lowerProperty.includes("cardholder name")) {
            context.cipher.card.cardholderName = context.importRecord[context.property];
            return true;
        }
        return false;
    }
    setCreditCardExpiry(context) {
        if (this.isNullOrWhitespace(context.cipher.card.expiration) &&
            context.lowerProperty.includes("expiry date") &&
            context.importRecord[context.property].length === 7) {
            context.cipher.card.expMonth = context.importRecord[context.property].substr(0, 2);
            if (context.cipher.card.expMonth[0] === "0") {
                context.cipher.card.expMonth = context.cipher.card.expMonth.substr(1, 1);
            }
            context.cipher.card.expYear = context.importRecord[context.property].substr(3, 4);
            return true;
        }
        return false;
    }
    setLoginPassword(context) {
        if (this.isNullOrWhitespace(context.cipher.login.password) &&
            context.lowerProperty === "password") {
            context.cipher.login.password = context.importRecord[context.property];
            return true;
        }
        return false;
    }
    setLoginUsername(context) {
        if (this.isNullOrWhitespace(context.cipher.login.username) &&
            context.lowerProperty === "username") {
            context.cipher.login.username = context.importRecord[context.property];
            return true;
        }
        return false;
    }
    setLoginUris(context) {
        if ((context.cipher.login.uris == null || context.cipher.login.uris.length === 0) &&
            context.lowerProperty === "urls") {
            const urls = context.importRecord[context.property].split(this.newLineRegex);
            context.cipher.login.uris = this.makeUriArray(urls);
            return true;
        }
        else if (context.lowerProperty === "url") {
            if (context.cipher.login.uris == null) {
                context.cipher.login.uris = [];
            }
            context.cipher.login.uris.concat(this.makeUriArray(context.importRecord[context.property]));
            return true;
        }
        return false;
    }
}

;// ../../libs/importer/src/importers/onepassword/onepassword-mac-csv-importer.ts




class OnePasswordMacCsvImporter extends OnePasswordCsvImporter {
    setCipherType(value, cipher) {
        const onePassType = this.getValueOrDefault(this.getProp(value, "type"), "Login");
        switch (onePassType) {
            case "Credit Card":
                cipher.type = CipherType.Card;
                cipher.card = new CardView();
                IgnoredProperties.push("type");
                break;
            case "Identity":
                cipher.type = CipherType.Identity;
                cipher.identity = new IdentityView();
                IgnoredProperties.push("type");
                break;
            case "Login":
            case "Secure Note":
                IgnoredProperties.push("type");
                break;
            default:
                break;
        }
    }
}

;// ../../libs/importer/src/importers/onepassword/onepassword-win-csv-importer.ts





class OnePasswordWinCsvImporter extends OnePasswordCsvImporter {
    constructor() {
        super();
        this.identityPropertyParsers.push(this.setIdentityAddress);
    }
    setCipherType(value, cipher) {
        cipher.type = CipherType.Login;
        cipher.login = new LoginView();
        if (!this.isNullOrWhitespace(this.getPropByRegexp(value, /\d+: number/i)) &&
            !this.isNullOrWhitespace(this.getPropByRegexp(value, /\d+: expiry date/i))) {
            cipher.type = CipherType.Card;
            cipher.card = new CardView();
        }
        if (!this.isNullOrWhitespace(this.getPropByRegexp(value, /name \d+: first name/i)) ||
            !this.isNullOrWhitespace(this.getPropByRegexp(value, /name \d+: initial/i)) ||
            !this.isNullOrWhitespace(this.getPropByRegexp(value, /name \d+: last name/i)) ||
            !this.isNullOrWhitespace(this.getPropByRegexp(value, /internet \d+: email/i))) {
            cipher.type = CipherType.Identity;
            cipher.identity = new IdentityView();
        }
    }
    setIdentityAddress(context) {
        if (context.lowerProperty.match(/address \d+: address/i)) {
            this.processKvp(context.cipher, "address", context.importRecord[context.property]);
            return true;
        }
        return false;
    }
    setCreditCardExpiry(context) {
        if (this.isNullOrWhitespace(context.cipher.card.expiration) &&
            context.lowerProperty.includes("expiry date")) {
            const expSplit = context.importRecord[context.property].split("/");
            context.cipher.card.expMonth = expSplit[0];
            if (context.cipher.card.expMonth[0] === "0" && context.cipher.card.expMonth.length === 2) {
                context.cipher.card.expMonth = context.cipher.card.expMonth.substr(1, 1);
            }
            context.cipher.card.expYear = expSplit[2].length > 4 ? expSplit[2].substr(0, 4) : expSplit[2];
            return true;
        }
        return false;
    }
}

;// ../../libs/importer/src/importers/onepassword/index.ts






;// ../../libs/importer/src/importers/padlock-csv-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore



class PadlockCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, false);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        let headers = null;
        results.forEach((value) => {
            if (headers == null) {
                headers = value.map((v) => v);
                return;
            }
            if (value.length < 2 || value.length !== headers.length) {
                return;
            }
            if (!this.isNullOrWhitespace(value[1])) {
                if (this.organization) {
                    const tags = value[1].split(",");
                    tags.forEach((tag) => {
                        tag = tag.trim();
                        let addCollection = true;
                        let collectionIndex = result.collections.length;
                        for (let i = 0; i < result.collections.length; i++) {
                            if (result.collections[i].name === tag) {
                                addCollection = false;
                                collectionIndex = i;
                                break;
                            }
                        }
                        if (addCollection) {
                            // FIXME use a different model if ID is not required.
                            // @ts-expect-error current functionality creates this view with no Id since its being imported.
                            const collection = new CollectionView({
                                name: tag,
                            });
                            result.collections.push(collection);
                        }
                        result.collectionRelationships.push([result.ciphers.length, collectionIndex]);
                    });
                }
                else {
                    const tags = value[1].split(",");
                    const tag = tags.length > 0 ? tags[0].trim() : null;
                    this.processFolder(result, tag);
                }
            }
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(value[0], "--");
            for (let i = 2; i < value.length; i++) {
                const header = headers[i].trim().toLowerCase();
                if (this.isNullOrWhitespace(value[i]) || this.isNullOrWhitespace(header)) {
                    continue;
                }
                if (this.usernameFieldNames.indexOf(header) > -1) {
                    cipher.login.username = value[i];
                }
                else if (this.passwordFieldNames.indexOf(header) > -1) {
                    cipher.login.password = value[i];
                }
                else if (this.uriFieldNames.indexOf(header) > -1) {
                    cipher.login.uris = this.makeUriArray(value[i]);
                }
                else {
                    this.processKvp(cipher, headers[i], value[i]);
                }
            }
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/passkeep-csv-importer.ts


class PassKeepCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            this.processFolder(result, this.getValue("category", value));
            const cipher = this.initLoginCipher();
            cipher.notes = this.getValue("description", value);
            cipher.name = this.getValueOrDefault(this.getValue("title", value), "--");
            cipher.login.username = this.getValue("username", value);
            cipher.login.password = this.getValue("password", value);
            cipher.login.uris = this.makeUriArray(this.getValue("site", value));
            this.processKvp(cipher, "Password 2", this.getValue("password2", value));
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
    getValue(key, value) {
        return this.getValueOrDefault(value[key], this.getValueOrDefault(value[" " + key]));
    }
}

;// ../../libs/importer/src/importers/passky/passky-json-importer.ts


class PasskyJsonImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const passkyExport = JSON.parse(data);
        if (passkyExport == null ||
            passkyExport.passwords == null ||
            passkyExport.passwords.length === 0) {
            result.success = false;
            return Promise.resolve(result);
        }
        if (passkyExport.encrypted == true) {
            result.success = false;
            result.errorMessage = "Unable to import an encrypted passky backup.";
            return Promise.resolve(result);
        }
        passkyExport.passwords.forEach((record) => {
            const cipher = this.initLoginCipher();
            cipher.name = record.website;
            cipher.login.username = record.username;
            cipher.login.password = record.password;
            cipher.login.uris = this.makeUriArray(record.website);
            cipher.notes = record.message;
            this.convertToNoteIfNeeded(cipher);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/passman-json-importer.ts


class PassmanJsonImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = JSON.parse(data);
        if (results == null || results.length === 0) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((credential) => {
            if (credential.tags != null && credential.tags.length > 0) {
                const folderName = credential.tags[0].text;
                this.processFolder(result, folderName);
            }
            const cipher = this.initLoginCipher();
            cipher.name = credential.label;
            cipher.login.username = this.getValueOrDefault(credential.username);
            if (this.isNullOrWhitespace(cipher.login.username)) {
                cipher.login.username = this.getValueOrDefault(credential.email);
            }
            else if (!this.isNullOrWhitespace(credential.email)) {
                cipher.notes = "Email: " + credential.email + "\n";
            }
            cipher.login.password = this.getValueOrDefault(credential.password);
            cipher.login.uris = this.makeUriArray(credential.url);
            cipher.notes += this.getValueOrDefault(credential.description, "");
            if (credential.otp != null) {
                cipher.login.totp = this.getValueOrDefault(credential.otp.secret);
            }
            if (credential.custom_fields != null) {
                credential.custom_fields.forEach((customField) => {
                    switch (customField.field_type) {
                        case "text":
                        case "password":
                            this.processKvp(cipher, customField.label, customField.value);
                            break;
                    }
                });
            }
            this.convertToNoteIfNeeded(cipher);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/passpack-csv-importer.ts



class PasspackCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            const tagsJson = !this.isNullOrWhitespace(value.Tags) ? JSON.parse(value.Tags) : null;
            const tags = tagsJson != null && tagsJson.tags != null && tagsJson.tags.length > 0
                ? tagsJson.tags
                    .map((tagJson) => {
                    try {
                        const t = JSON.parse(tagJson);
                        return this.getValueOrDefault(t.tag);
                    }
                    catch (_a) {
                        // Ignore error
                    }
                    return null;
                })
                    .filter((t) => !this.isNullOrWhitespace(t))
                : null;
            if (this.organization && tags != null && tags.length > 0) {
                tags.forEach((tag) => {
                    let addCollection = true;
                    let collectionIndex = result.collections.length;
                    for (let i = 0; i < result.collections.length; i++) {
                        if (result.collections[i].name === tag) {
                            addCollection = false;
                            collectionIndex = i;
                            break;
                        }
                    }
                    if (addCollection) {
                        // FIXME use a different model if ID is not required.
                        // @ts-expect-error current functionality creates this view with no Id since its being imported.
                        const collection = new CollectionView({
                            name: tag,
                        });
                        result.collections.push(collection);
                    }
                    result.collectionRelationships.push([result.ciphers.length, collectionIndex]);
                });
            }
            else if (!this.organization && tags != null && tags.length > 0) {
                this.processFolder(result, tags[0]);
            }
            const cipher = this.initLoginCipher();
            cipher.notes = this.getValueOrDefault(value.Notes, "");
            cipher.notes += "\n\n" + this.getValueOrDefault(value["Shared Notes"], "") + "\n";
            cipher.name = this.getValueOrDefault(value["Entry Name"], "--");
            cipher.login.username = this.getValueOrDefault(value["User ID"]);
            cipher.login.password = this.getValueOrDefault(value.Password);
            cipher.login.uris = this.makeUriArray(value.URL);
            if (value.__parsed_extra != null && value.__parsed_extra.length > 0) {
                value.__parsed_extra.forEach((extra) => {
                    if (!this.isNullOrWhitespace(extra)) {
                        cipher.notes += "\n" + extra;
                    }
                });
            }
            const fieldsJson = !this.isNullOrWhitespace(value["Extra Fields"])
                ? JSON.parse(value["Extra Fields"])
                : null;
            const fields = fieldsJson != null && fieldsJson.extraFields != null && fieldsJson.extraFields.length > 0
                ? fieldsJson.extraFields.map((fieldJson) => {
                    try {
                        return JSON.parse(fieldJson);
                    }
                    catch (_a) {
                        // Ignore error
                    }
                    return null;
                })
                : null;
            if (fields != null) {
                fields.forEach((f) => {
                    if (f != null) {
                        this.processKvp(cipher, f.name, f.data);
                    }
                });
            }
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/passwordagent-csv-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


class PasswordAgentCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, false);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        let newVersion = true;
        results.forEach((value) => {
            if (value.length !== 5 && value.length < 9) {
                return;
            }
            const altFormat = value.length === 10 && value[0] === "0";
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(value[altFormat ? 1 : 0], "--");
            cipher.login.username = this.getValueOrDefault(value[altFormat ? 2 : 1]);
            cipher.login.password = this.getValueOrDefault(value[altFormat ? 3 : 2]);
            if (value.length === 5) {
                newVersion = false;
                cipher.notes = this.getValueOrDefault(value[4]);
                cipher.login.uris = this.makeUriArray(value[3]);
            }
            else {
                const folder = this.getValueOrDefault(value[altFormat ? 9 : 8], "(None)");
                let folderName = folder !== "(None)" ? folder.split("\\").join("/") : null;
                if (folderName != null) {
                    folderName = folder.split(" > ").join("/");
                    folderName = folder.split(">").join("/");
                }
                this.processFolder(result, folderName);
                cipher.notes = this.getValueOrDefault(value[altFormat ? 5 : 3]);
                cipher.login.uris = this.makeUriArray(value[4]);
            }
            this.convertToNoteIfNeeded(cipher);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        if (newVersion && this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/passwordboss-json-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore





class PasswordBossJsonImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = JSON.parse(data);
        if (results == null || results.items == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        const foldersMap = new Map();
        results.folders.forEach((value) => {
            foldersMap.set(value.id, value.name);
        });
        const foldersIndexMap = new Map();
        foldersMap.forEach((val, key) => {
            foldersIndexMap.set(key, result.folders.length);
            const f = new FolderView();
            f.name = val;
            result.folders.push(f);
        });
        results.items.forEach((value) => {
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(value.name, "--");
            cipher.login.uris = this.makeUriArray(value.login_url);
            if (value.folder != null && foldersIndexMap.has(value.folder)) {
                result.folderRelationships.push([result.ciphers.length, foldersIndexMap.get(value.folder)]);
            }
            if (value.identifiers == null) {
                return;
            }
            if (!this.isNullOrWhitespace(value.identifiers.notes)) {
                cipher.notes = value.identifiers.notes.split("\\r\\n").join("\n").split("\\n").join("\n");
            }
            if (value.type === "CreditCard") {
                cipher.card = new CardView();
                cipher.type = CipherType.Card;
            }
            for (const property in value.identifiers) {
                // eslint-disable-next-line
                if (!value.identifiers.hasOwnProperty(property)) {
                    continue;
                }
                const valObj = value.identifiers[property];
                const val = valObj != null ? valObj.toString() : null;
                if (this.isNullOrWhitespace(val) ||
                    property === "notes" ||
                    property === "ignoreItemInSecurityScore") {
                    continue;
                }
                if (property === "custom_fields") {
                    valObj.forEach((cf) => {
                        this.processKvp(cipher, cf.name, cf.value);
                    });
                    continue;
                }
                if (cipher.type === CipherType.Card) {
                    if (property === "cardNumber") {
                        cipher.card.number = val;
                        cipher.card.brand = CardView.getCardBrandByPatterns(cipher.card.number);
                        continue;
                    }
                    else if (property === "nameOnCard") {
                        cipher.card.cardholderName = val;
                        continue;
                    }
                    else if (property === "security_code") {
                        cipher.card.code = val;
                        continue;
                    }
                    else if (property === "expires") {
                        try {
                            const expDate = new Date(val);
                            cipher.card.expYear = expDate.getFullYear().toString();
                            cipher.card.expMonth = (expDate.getMonth() + 1).toString();
                        }
                        catch (_a) {
                            // Ignore error
                        }
                        continue;
                    }
                    else if (property === "cardType") {
                        continue;
                    }
                }
                else {
                    if ((property === "username" || property === "email") &&
                        this.isNullOrWhitespace(cipher.login.username)) {
                        cipher.login.username = val;
                        continue;
                    }
                    else if (property === "password") {
                        cipher.login.password = val;
                        continue;
                    }
                    else if (property === "totp") {
                        cipher.login.totp = val;
                        continue;
                    }
                    else if ((cipher.login.uris == null || cipher.login.uris.length === 0) &&
                        this.uriFieldNames.indexOf(property) > -1) {
                        cipher.login.uris = this.makeUriArray(val);
                        continue;
                    }
                }
                this.processKvp(cipher, property, val);
            }
            this.convertToNoteIfNeeded(cipher);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/password-depot/types/password-depot-item-type.ts
/** This object represents the different item types in Password Depot */
const PasswordDepotItemType = Object.freeze({
    Password: "0",
    CreditCard: "1",
    SoftwareLicense: "2",
    Identity: "3",
    Information: "4",
    Banking: "5",
    EncryptedFile: "6",
    Document: "7",
    RDP: "8",
    Putty: "9",
    TeamViewer: "10",
    Certificate: "11",
});

;// ../../libs/importer/src/importers/password-depot/types/password-depot-custom-field-type.ts
/** This object represents the different custom field types in Password Depot */
const PasswordDepotCustomFieldType = Object.freeze({
    Password: "1",
    Memo: "2",
    Date: "3",
    Number: "4",
    Boolean: "5",
    Decimal: "6",
    Email: "7",
    URL: "8",
});

;// ../../libs/importer/src/importers/password-depot/types/index.ts



;// ../../libs/importer/src/importers/password-depot/password-depot-17-xml-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore









/**
 * Importer for Password Depot 17 xml files.
 * @see https://www.password-depot.de/
 * It provides methods to parse the XML data, extract relevant information, and create cipher objects
 */
class PasswordDepot17XmlImporter extends BaseImporter {
    constructor() {
        super(...arguments);
        this.result = new ImportResult();
        this._favouritesLookupTable = new Set();
    }
    // Parse the XML data from the Password Depot export file and extracts the relevant information
    parse(data) {
        const doc = this.parseXml(data);
        if (doc == null) {
            this.result.success = false;
            return Promise.resolve(this.result);
        }
        // Check if the root node is present
        const rootNode = doc.querySelector("passwordfile");
        if (rootNode == null) {
            this.result.errorMessage = "Missing `passwordfile` node.";
            this.result.success = false;
            return Promise.resolve(this.result);
        }
        // Check if the version is supported
        const headerNode = this.querySelectorDirectChild(rootNode, "header");
        if (headerNode == null) {
            this.result.success = false;
            return Promise.resolve(this.result);
        }
        let versionNode = this.querySelectorDirectChild(headerNode, "version");
        if (versionNode == null) {
            // Adding a fallback for MacOS Password Depot 17.0 export files
            // These files do not have a version node, but a dataformat node instead
            versionNode = this.querySelectorDirectChild(headerNode, "dataformat");
            if (versionNode == null) {
                this.result.success = false;
                return Promise.resolve(this.result);
            }
        }
        const version = versionNode.textContent;
        if (!version.startsWith("17")) {
            this.result.errorMessage = "Unsupported export version detected - (only 17.0 is supported)";
            this.result.success = false;
            return Promise.resolve(this.result);
        }
        // Abort import if the file is encrypted
        const encryptedNode = this.querySelectorDirectChild(headerNode, "encrypted");
        if (encryptedNode != null && encryptedNode.textContent == "True") {
            this.result.errorMessage = "Encrypted Password Depot files are not supported.";
            this.result.success = false;
            return Promise.resolve(this.result);
        }
        // Check if the passwords node is present
        // This node contains all the password entries
        const passwordsNode = rootNode.querySelector("passwords");
        if (passwordsNode == null) {
            this.result.errorMessage = "Missing `passwordfile > passwords` node.";
            this.result.success = false;
            return Promise.resolve(this.result);
        }
        this.buildFavouritesLookupTable(rootNode);
        this.querySelectorAllDirectChild(passwordsNode, "group").forEach((group) => {
            this.traverse(group, "");
        });
        if (this.organization) {
            this.moveFoldersToCollections(this.result);
        }
        this.result.success = true;
        return Promise.resolve(this.result);
    }
    // Traverses the XML tree and processes each node
    // It starts from the root node and goes through each group and item
    // This method is recursive and handles nested groups
    traverse(node, groupPrefixName) {
        const folderIndex = this.result.folders.length;
        let groupName = groupPrefixName;
        if (groupName !== "") {
            groupName += "/";
        }
        // Check if the group has a fingerprint attribute (GUID of a folder)
        const groupFingerprint = node.attributes.getNamedItem("fingerprint");
        if ((groupFingerprint === null || groupFingerprint === void 0 ? void 0 : groupFingerprint.textContent) != "" && groupFingerprint.textContent != "null") {
            const nameEl = node.attributes.getNamedItem("name");
            groupName += nameEl == null ? "-" : nameEl.textContent;
            const folder = new FolderView();
            folder.name = groupName;
            this.result.folders.push(folder);
        }
        this.querySelectorAllDirectChild(node, "item").forEach((entry) => {
            const cipherIndex = this.result.ciphers.length;
            const cipher = this.initLoginCipher();
            //Set default item type similar how we default to Login in other importers
            let sourceType = PasswordDepotItemType.Password;
            const entryFields = entry.children;
            for (let i = 0; i < entryFields.length; i++) {
                const entryField = entryFields[i];
                // Skip processing historical entries
                if (entryField.tagName === "hitems") {
                    continue;
                }
                if (entryField.tagName === "description") {
                    cipher.name = entryField.textContent;
                    continue;
                }
                if (entryField.tagName === "comment") {
                    cipher.notes = entryField.textContent;
                    continue;
                }
                if (entryField.tagName === "type") {
                    sourceType = entryField.textContent;
                    switch (sourceType) {
                        case PasswordDepotItemType.Password:
                        case PasswordDepotItemType.RDP:
                        case PasswordDepotItemType.Putty:
                        case PasswordDepotItemType.TeamViewer:
                        case PasswordDepotItemType.Banking:
                        case PasswordDepotItemType.Certificate:
                        case PasswordDepotItemType.EncryptedFile:
                            cipher.type = CipherType.Login;
                            cipher.login = new LoginView();
                            break;
                        case PasswordDepotItemType.CreditCard:
                            cipher.type = CipherType.Card;
                            cipher.card = new CardView();
                            break;
                        case PasswordDepotItemType.SoftwareLicense:
                        case PasswordDepotItemType.Information:
                        case PasswordDepotItemType.Document:
                            cipher.type = CipherType.SecureNote;
                            cipher.secureNote = new SecureNoteView();
                            cipher.secureNote.type = SecureNoteType.Generic;
                            break;
                        case PasswordDepotItemType.Identity:
                            cipher.type = CipherType.Identity;
                            cipher.identity = new IdentityView();
                            break;
                    }
                    continue;
                }
                if (sourceType === PasswordDepotItemType.Password ||
                    sourceType === PasswordDepotItemType.RDP ||
                    sourceType === PasswordDepotItemType.Putty ||
                    sourceType === PasswordDepotItemType.TeamViewer ||
                    sourceType === PasswordDepotItemType.Banking ||
                    sourceType === PasswordDepotItemType.Certificate ||
                    sourceType === PasswordDepotItemType.EncryptedFile) {
                    if (this.parseLoginFields(entryField, cipher)) {
                        continue;
                    }
                }
                // fingerprint is the GUID of the entry
                // Base on the previously parsed favourites, we can identify an entry and set the favorite flag accordingly
                if (entryField.tagName === "fingerprint") {
                    if (this._favouritesLookupTable.has(entryField.textContent)) {
                        cipher.favorite = true;
                    }
                }
                if (entryField.tagName === "customfields") {
                    this.parseCustomFields(entryField, sourceType, cipher);
                    continue;
                }
                if (sourceType === PasswordDepotItemType.Banking && entryField.tagName === "tans") {
                    this.querySelectorAllDirectChild(entryField, "tan").forEach((tanEntry) => {
                        this.parseBankingTANs(tanEntry, cipher);
                    });
                    continue;
                }
                this.processKvp(cipher, entryField.tagName, entryField.textContent, FieldType.Text);
            }
            this.cleanupCipher(cipher);
            this.result.ciphers.push(cipher);
            if (groupName !== "") {
                this.result.folderRelationships.push([cipherIndex, folderIndex]);
            }
        });
        this.querySelectorAllDirectChild(node, "group").forEach((group) => {
            this.traverse(group, groupName);
        });
    }
    // Parses custom fields and adds them to the cipher
    // It iterates through all the custom fields and adds them to the cipher
    parseCustomFields(entryField, sourceType, cipher) {
        this.querySelectorAllDirectChild(entryField, "field").forEach((customField) => {
            const customFieldObject = this.parseCustomField(customField);
            if (customFieldObject == null) {
                return;
            }
            switch (sourceType) {
                case PasswordDepotItemType.CreditCard:
                    if (this.parseCreditCardCustomFields(customFieldObject, cipher)) {
                        return;
                    }
                    break;
                case PasswordDepotItemType.Identity:
                    if (this.parseIdentityCustomFields(customFieldObject, cipher)) {
                        return;
                    }
                    break;
                case PasswordDepotItemType.Information:
                    if (this.parseInformationCustomFields(customFieldObject, cipher)) {
                        return;
                    }
                    break;
                default:
                    // For other types, we will process the custom field as a regular key-value pair
                    break;
            }
            this.processKvp(cipher, customFieldObject.name, customFieldObject.value, customFieldObject.type);
        });
    }
    // Parses login fields and adds them to the cipher
    parseLoginFields(entryField, cipher) {
        if (entryField.tagName === "username") {
            cipher.login.username = entryField.textContent;
            return true;
        }
        if (entryField.tagName === "password") {
            cipher.login.password = entryField.textContent;
            return true;
        }
        if (entryField.tagName === "url") {
            cipher.login.uris = this.makeUriArray(entryField.textContent);
            return true;
        }
        return false;
    }
    // Parses a custom field and adds it to the cipher
    parseCustomField(customField) {
        let key = undefined;
        let value = undefined;
        let sourceFieldType = PasswordDepotCustomFieldType.Memo;
        let visible = undefined;
        // A custom field is represented by a <field> element
        // On exports from the Windows clients: It contains a <name>, <value>, and optionally a <type> and <visible> element
        // On exports from the MacOs clients the key-values are defined as xml attributes instead of child nodes
        if (customField.hasAttributes()) {
            key = customField.getAttribute("name");
            if (key == null) {
                return null;
            }
            value = customField.getAttribute("value");
            const typeAttr = customField.getAttribute("type");
            sourceFieldType =
                typeAttr != null
                    ? typeAttr
                    : PasswordDepotCustomFieldType.Memo;
            visible = customField.getAttribute("visible");
        }
        else {
            const keyEl = this.querySelectorDirectChild(customField, "name");
            key = keyEl != null ? keyEl.textContent : null;
            if (key == null) {
                return null;
            }
            const valueEl = this.querySelectorDirectChild(customField, "value");
            value = valueEl != null ? valueEl.textContent : null;
            const typeEl = this.querySelectorDirectChild(customField, "type");
            sourceFieldType =
                typeEl != null
                    ? typeEl.textContent
                    : PasswordDepotCustomFieldType.Memo;
            const visibleEl = this.querySelectorDirectChild(customField, "visible");
            visible = visibleEl != null ? visibleEl.textContent : null;
        }
        if (sourceFieldType === PasswordDepotCustomFieldType.Date) {
            if (!isNaN(value)) {
                // Convert excel date format to JavaScript date
                const numericValue = parseInt(value);
                const secondsInDay = 86400;
                const missingLeapYearDays = secondsInDay * 1000;
                value = new Date((numericValue - (25567 + 2)) * missingLeapYearDays).toLocaleDateString();
            }
        }
        if (sourceFieldType === PasswordDepotCustomFieldType.Password) {
            return { name: key, value: value, type: FieldType.Hidden, linkedId: null };
        }
        if (sourceFieldType === PasswordDepotCustomFieldType.Boolean) {
            return { name: key, value: value, type: FieldType.Boolean, linkedId: null };
        }
        if (visible == "0") {
            return { name: key, value: value, type: FieldType.Hidden, linkedId: null };
        }
        return { name: key, value: value, type: FieldType.Text, linkedId: null };
    }
    // Parses credit card fields and adds them to the cipher
    parseCreditCardCustomFields(customField, cipher) {
        if (customField.name === "IDS_CardHolder") {
            cipher.card.cardholderName = customField.value;
            return true;
        }
        if (customField.name === "IDS_CardNumber") {
            cipher.card.number = customField.value;
            cipher.card.brand = CardView.getCardBrandByPatterns(cipher.card.number);
            return true;
        }
        if (customField.name === "IDS_CardExpires") {
            this.setCardExpiration(cipher, customField.value);
            return true;
        }
        if (customField.name === "IDS_CardCode") {
            cipher.card.code = customField.value;
            return true;
        }
        return false;
    }
    // Parses identity fields and adds them to the cipher
    parseIdentityCustomFields(customField, cipher) {
        if (customField.name === "IDS_IdentityName") {
            this.processFullName(cipher, customField.value);
            return true;
        }
        if (customField.name === "IDS_IdentityEmail") {
            cipher.identity.email = customField.value;
            return true;
        }
        if (customField.name === "IDS_IdentityFirstName") {
            cipher.identity.firstName = customField.value;
            return true;
        }
        if (customField.name === "IDS_IdentityLastName") {
            cipher.identity.lastName = customField.value;
            return true;
        }
        if (customField.name === "IDS_IdentityCompany") {
            cipher.identity.company = customField.value;
            return true;
        }
        if (customField.name === "IDS_IdentityAddress1") {
            cipher.identity.address1 = customField.value;
            return true;
        }
        if (customField.name === "IDS_IdentityAddress2") {
            cipher.identity.address2 = customField.value;
            return true;
        }
        if (customField.name === "IDS_IdentityCity") {
            cipher.identity.city = customField.value;
            return true;
        }
        if (customField.name === "IDS_IdentityState") {
            cipher.identity.state = customField.value;
            return true;
        }
        if (customField.name === "IDS_IdentityZIP") {
            cipher.identity.postalCode = customField.value;
            return true;
        }
        if (customField.name === "IDS_IdentityCountry") {
            cipher.identity.country = customField.value;
            return true;
        }
        if (customField.name === "IDS_IdentityPhone") {
            cipher.identity.phone = customField.value;
            return true;
        }
        return false;
    }
    // Parses information custom fields and adds them to the cipher
    parseInformationCustomFields(customField, cipher) {
        if (customField.name === "IDS_InformationText") {
            cipher.notes = customField.value;
            return true;
        }
        return false;
    }
    // Parses TAN objects and adds them to the cipher
    // It iterates through all the TAN fields and adds them to the cipher
    parseBankingTANs(TANsField, cipher) {
        let tanNumber = "0";
        const entryFields = TANsField.children;
        for (let i = 0; i < entryFields.length; i++) {
            const entryField = entryFields[i];
            if (entryField.tagName === "number") {
                tanNumber = entryField.textContent;
                continue;
            }
            this.processKvp(cipher, `tan_${tanNumber}_${entryField.tagName}`, entryField.textContent);
        }
    }
    // Parses the favourites-node from the XML file, which contains a base64 encoded string
    // The string contains the fingerprints/GUIDs of the favourited entries, separated by new lines
    buildFavouritesLookupTable(rootNode) {
        const favouritesNode = this.querySelectorDirectChild(rootNode, "favorites");
        if (favouritesNode == null) {
            return;
        }
        const decodedBase64String = atob(favouritesNode.textContent);
        if (decodedBase64String.indexOf("\r\n") > 0) {
            decodedBase64String.split("\r\n").forEach((line) => {
                this._favouritesLookupTable.add(line);
            });
            return;
        }
        decodedBase64String.split("\n").forEach((line) => {
            this._favouritesLookupTable.add(line);
        });
    }
}

;// ../../libs/importer/src/importers/password-depot/index.ts


;// ../../libs/importer/src/importers/passworddragon-xml-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


class PasswordDragonXmlImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const doc = this.parseXml(data);
        if (doc == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        const records = doc.querySelectorAll("PasswordManager > record");
        Array.from(records).forEach((record) => {
            const category = this.querySelectorDirectChild(record, "Category");
            const categoryText = category != null &&
                !this.isNullOrWhitespace(category.textContent) &&
                category.textContent !== "Unfiled"
                ? category.textContent
                : null;
            this.processFolder(result, categoryText);
            const accountName = this.querySelectorDirectChild(record, "Account-Name");
            const userId = this.querySelectorDirectChild(record, "User-Id");
            const password = this.querySelectorDirectChild(record, "Password");
            const url = this.querySelectorDirectChild(record, "URL");
            const notes = this.querySelectorDirectChild(record, "Notes");
            const cipher = this.initLoginCipher();
            cipher.name =
                accountName != null ? this.getValueOrDefault(accountName.textContent, "--") : "--";
            cipher.notes = notes != null ? this.getValueOrDefault(notes.textContent) : "";
            cipher.login.username = userId != null ? this.getValueOrDefault(userId.textContent) : null;
            cipher.login.password =
                password != null ? this.getValueOrDefault(password.textContent) : null;
            cipher.login.uris = url != null ? this.makeUriArray(url.textContent) : null;
            const attributes = [];
            for (let i = 1; i <= 10; i++) {
                attributes.push("Attribute-" + i);
            }
            this.querySelectorAllDirectChild(record, attributes.join(",")).forEach((attr) => {
                if (this.isNullOrWhitespace(attr.textContent) || attr.textContent === "null") {
                    return;
                }
                this.processKvp(cipher, attr.tagName, attr.textContent);
            });
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/passwordsafe-xml-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


/** This is the importer for the xml format from pwsafe.org  */
class PasswordSafeXmlImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const doc = this.parseXml(data);
        if (doc == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        const passwordSafe = doc.querySelector("passwordsafe");
        if (passwordSafe == null) {
            result.errorMessage = "Missing `passwordsafe` node.";
            result.success = false;
            return Promise.resolve(result);
        }
        const notesDelimiter = passwordSafe.getAttribute("delimiter");
        const entries = doc.querySelectorAll("passwordsafe > entry");
        Array.from(entries).forEach((entry) => {
            const group = this.querySelectorDirectChild(entry, "group");
            const groupText = group != null && !this.isNullOrWhitespace(group.textContent)
                ? group.textContent.split(".").join("/")
                : null;
            this.processFolder(result, groupText);
            const title = this.querySelectorDirectChild(entry, "title");
            const username = this.querySelectorDirectChild(entry, "username");
            const email = this.querySelectorDirectChild(entry, "email");
            const password = this.querySelectorDirectChild(entry, "password");
            const url = this.querySelectorDirectChild(entry, "url");
            const notes = this.querySelectorDirectChild(entry, "notes");
            const cipher = this.initLoginCipher();
            cipher.name = title != null ? this.getValueOrDefault(title.textContent, "--") : "--";
            cipher.notes =
                notes != null
                    ? this.getValueOrDefault(notes.textContent, "").split(notesDelimiter).join("\n")
                    : null;
            cipher.login.username =
                username != null ? this.getValueOrDefault(username.textContent) : null;
            cipher.login.password =
                password != null ? this.getValueOrDefault(password.textContent) : null;
            cipher.login.uris = url != null ? this.makeUriArray(url.textContent) : null;
            if (this.isNullOrWhitespace(cipher.login.username) && email != null) {
                cipher.login.username = this.getValueOrDefault(email.textContent);
            }
            else if (email != null && !this.isNullOrWhitespace(email.textContent)) {
                cipher.notes = this.isNullOrWhitespace(cipher.notes)
                    ? "Email: " + email.textContent
                    : cipher.notes + "\n" + "Email: " + email.textContent;
            }
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/passwordwallet-txt-importer.ts


class PasswordWalletTxtImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, false);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            if (value.length < 1) {
                return;
            }
            if (value.length > 5) {
                this.processFolder(result, value[5]);
            }
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(value[0], "--");
            if (value.length > 4) {
                cipher.notes = this.getValueOrDefault(value[4], "").split("¬").join("\n");
            }
            if (value.length > 2) {
                cipher.login.username = this.getValueOrDefault(value[2]);
            }
            if (value.length > 3) {
                cipher.login.password = this.getValueOrDefault(value[3]);
            }
            if (value.length > 1) {
                cipher.login.uris = this.makeUriArray(value[1]);
            }
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/passsordxp/dutch-csv-headers.ts
const dutchHeaderTranslations = {
    Titel: "Title",
    Gebruikersnaam: "Username",
    Wachtwoord: "Password",
    Gewijzigd: "Modified",
    Gemaakt: "Created",
    "Verloopt op": "Expire on",
    Beschrijving: "Description",
    "Gewijzigd door": "Modified by",
};

;// ../../libs/importer/src/importers/passsordxp/german-csv-headers.ts
const germanHeaderTranslations = {
    Titel: "Title",
    Benutzername: "Username",
    Konto: "Account",
    Passwort: "Password",
    "Geändert am": "Modified",
    "Erstellt am": "Created",
    "Läuft ab am": "Expire on",
    Beschreibung: "Description",
    "Geändert von": "Modified by",
};

;// ../../libs/importer/src/importers/passsordxp/passwordxp-csv-importer.ts



const passwordxp_csv_importer_mappedColumns = new Set(["Title", "Username", "URL", "Password", "Description"]);


/* Translates the headers from non-English to English
 * This is necessary because the parser only maps English headers to ciphers
 * Currently only supports German and Dutch translations
 */
function translateIntoEnglishHeaders(header) {
    const translations = Object.assign(Object.assign({ 
        // The header column 'User name' is parsed by the parser, but cannot be used as a variable. This converts it to a valid variable name, prior to parsing.
        "User name": "Username" }, germanHeaderTranslations), dutchHeaderTranslations);
    return translations[header] || header;
}
/**
 * PasswordXP CSV importer
 */
class PasswordXPCsvImporter extends BaseImporter {
    /**
     * Parses the PasswordXP CSV data.
     * @param data
     */
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true, {
            skipEmptyLines: true,
            transformHeader: translateIntoEnglishHeaders,
        });
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        // If the first row (header check) does not contain the column "Title", then the data is invalid (no translation found)
        if (!results[0].Title) {
            result.success = false;
            return Promise.resolve(result);
        }
        let currentFolderName = "";
        results.forEach((row) => {
            // Skip rows starting with '>>>' as they indicate items following have no folder assigned to them
            if (row.Title == ">>>") {
                return;
            }
            const title = row.Title;
            // If the title is in the format [title], then it is a folder name
            if (title.startsWith("[") && title.endsWith("]")) {
                currentFolderName = title.startsWith("/")
                    ? title.replace("/", "")
                    : title.substring(1, title.length - 1);
                return;
            }
            if (!utils_Utils.isNullOrWhitespace(currentFolderName)) {
                this.processFolder(result, currentFolderName);
            }
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(row.Title);
            cipher.login.username = this.getValueOrDefault(row.Username);
            cipher.notes = this.getValueOrDefault(row.Description);
            cipher.login.uris = this.makeUriArray(row.URL);
            cipher.login.password = this.getValueOrDefault(row.Password);
            this.importUnmappedFields(cipher, row, passwordxp_csv_importer_mappedColumns);
            this.convertToNoteIfNeeded(cipher);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
    importUnmappedFields(cipher, row, mappedValues) {
        const unmappedFields = Object.keys(row).filter((x) => !mappedValues.has(x));
        unmappedFields.forEach((key) => {
            const item = row;
            this.processKvp(cipher, key, item[key]);
        });
    }
}

;// ../../libs/importer/src/importers/protonpass/protonpass-import-utils.ts
function processNames(fullname, firstname, middlename, lastname) {
    let mappedFirstName = firstname;
    let mappedMiddleName = middlename;
    let mappedLastName = lastname;
    if (fullname) {
        const parts = fullname.trim().split(/\s+/);
        // Assign parts to first, middle, and last name based on the number of parts
        mappedFirstName = parts[0] || firstname;
        mappedLastName = parts.length > 1 ? parts[parts.length - 1] : lastname;
        mappedMiddleName = parts.length > 2 ? parts.slice(1, -1).join(" ") : middlename;
    }
    return { mappedFirstName, mappedMiddleName, mappedLastName };
}

;// ../../libs/importer/src/importers/protonpass/types/protonpass-json-type.ts
/**
 * Proton Pass item states as a const object.
 * Represents the different states an item can be in (active or trashed).
 */
const ProtonPassItemState = Object.freeze({
    ACTIVE: 1,
    TRASHED: 2,
});

;// ../../libs/importer/src/importers/protonpass/protonpass-json-importer.ts








class ProtonPassJsonImporter extends BaseImporter {
    constructor(i18nService) {
        super();
        this.i18nService = i18nService;
        this.mappedIdentityItemKeys = [
            "fullName",
            "firstName",
            "middleName",
            "lastName",
            "email",
            "phoneNumber",
            "company",
            "socialSecurityNumber",
            "passportNumber",
            "licenseNumber",
            "organization",
            "streetAddress",
            "floor",
            "county",
            "city",
            "stateOrProvince",
            "zipOrPostalCode",
            "countryOrRegion",
        ];
        this.identityItemExtraFieldsKeys = [
            "extraPersonalDetails",
            "extraAddressDetails",
            "extraContactDetails",
            "extraWorkDetails",
            "extraSections",
        ];
    }
    processIdentityItemUnmappedAndExtraFields(cipher, identityItem) {
        Object.keys(identityItem).forEach((key) => {
            if (!this.mappedIdentityItemKeys.includes(key) &&
                !this.identityItemExtraFieldsKeys.includes(key)) {
                this.processKvp(cipher, key, identityItem[key]);
                return;
            }
            if (this.identityItemExtraFieldsKeys.includes(key)) {
                if (key !== "extraSections") {
                    const extraFields = identityItem[key];
                    extraFields === null || extraFields === void 0 ? void 0 : extraFields.forEach((extraField) => {
                        this.processKvp(cipher, extraField.fieldName, extraField.data.content, extraField.type === "hidden" ? FieldType.Hidden : FieldType.Text);
                    });
                }
                else {
                    const extraSections = identityItem[key];
                    extraSections === null || extraSections === void 0 ? void 0 : extraSections.forEach((extraSection) => {
                        var _a;
                        (_a = extraSection.sectionFields) === null || _a === void 0 ? void 0 : _a.forEach((extraField) => {
                            this.processKvp(cipher, extraField.fieldName, extraField.data.content, extraField.type === "hidden" ? FieldType.Hidden : FieldType.Text);
                        });
                    });
                }
            }
        });
    }
    parse(data) {
        var _a, _b;
        const result = new ImportResult();
        const results = JSON.parse(data);
        if (results == null || results.vaults == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        if (results.encrypted) {
            result.success = false;
            result.errorMessage = this.i18nService.t("unsupportedEncryptedImport");
            return Promise.resolve(result);
        }
        for (const [, vault] of Object.entries(results.vaults)) {
            for (const item of vault.items) {
                if (item.state == ProtonPassItemState.TRASHED) {
                    continue;
                }
                const cipher = this.initLoginCipher();
                cipher.name = this.getValueOrDefault(item.data.metadata.name, "--");
                cipher.notes = this.getValueOrDefault(item.data.metadata.note);
                cipher.favorite = item.pinned;
                switch (item.data.type) {
                    case "login": {
                        const loginContent = item.data.content;
                        cipher.login.uris = this.makeUriArray(loginContent.urls);
                        cipher.login.username = this.getValueOrDefault(loginContent.itemUsername);
                        // if the cipher has no username then the email is used as the username
                        if (cipher.login.username == null) {
                            cipher.login.username = this.getValueOrDefault(loginContent.itemEmail);
                        }
                        else {
                            this.processKvp(cipher, "email", loginContent.itemEmail);
                        }
                        cipher.login.password = this.getValueOrDefault(loginContent.password);
                        cipher.login.totp = this.getValueOrDefault(loginContent.totpUri);
                        for (const extraField of item.data.extraFields) {
                            this.processKvp(cipher, extraField.fieldName, extraField.type == "totp" ? extraField.data.totpUri : extraField.data.content, extraField.type == "text" ? FieldType.Text : FieldType.Hidden);
                        }
                        break;
                    }
                    case "note":
                        cipher.type = CipherType.SecureNote;
                        cipher.secureNote = new SecureNoteView();
                        cipher.secureNote.type = SecureNoteType.Generic;
                        break;
                    case "creditCard": {
                        const creditCardContent = item.data.content;
                        cipher.type = CipherType.Card;
                        cipher.card = new CardView();
                        cipher.card.cardholderName = this.getValueOrDefault(creditCardContent.cardholderName);
                        cipher.card.number = this.getValueOrDefault(creditCardContent.number);
                        cipher.card.brand = CardView.getCardBrandByPatterns(creditCardContent.number);
                        cipher.card.code = this.getValueOrDefault(creditCardContent.verificationNumber);
                        if (!this.isNullOrWhitespace(creditCardContent.expirationDate)) {
                            cipher.card.expMonth = creditCardContent.expirationDate.substring(5, 7);
                            cipher.card.expMonth = cipher.card.expMonth.replace(/^0+/, "");
                            cipher.card.expYear = creditCardContent.expirationDate.substring(0, 4);
                        }
                        if (!this.isNullOrWhitespace(creditCardContent.pin)) {
                            this.processKvp(cipher, "PIN", creditCardContent.pin, FieldType.Hidden);
                        }
                        break;
                    }
                    case "identity": {
                        const identityContent = item.data.content;
                        cipher.type = CipherType.Identity;
                        cipher.identity = new IdentityView();
                        const { mappedFirstName, mappedMiddleName, mappedLastName } = processNames(this.getValueOrDefault(identityContent.fullName), this.getValueOrDefault(identityContent.firstName), this.getValueOrDefault(identityContent.middleName), this.getValueOrDefault(identityContent.lastName));
                        cipher.identity.firstName = mappedFirstName;
                        cipher.identity.middleName = mappedMiddleName;
                        cipher.identity.lastName = mappedLastName;
                        cipher.identity.email = this.getValueOrDefault(identityContent.email);
                        cipher.identity.phone = this.getValueOrDefault(identityContent.phoneNumber);
                        cipher.identity.company = this.getValueOrDefault(identityContent.company);
                        cipher.identity.ssn = this.getValueOrDefault(identityContent.socialSecurityNumber);
                        cipher.identity.passportNumber = this.getValueOrDefault(identityContent.passportNumber);
                        cipher.identity.licenseNumber = this.getValueOrDefault(identityContent.licenseNumber);
                        const address3 = `${(_a = identityContent.floor) !== null && _a !== void 0 ? _a : ""} ${(_b = identityContent.county) !== null && _b !== void 0 ? _b : ""}`.trim();
                        cipher.identity.address1 = this.getValueOrDefault(identityContent.organization);
                        cipher.identity.address2 = this.getValueOrDefault(identityContent.streetAddress);
                        cipher.identity.address3 = this.getValueOrDefault(address3);
                        cipher.identity.city = this.getValueOrDefault(identityContent.city);
                        cipher.identity.state = this.getValueOrDefault(identityContent.stateOrProvince);
                        cipher.identity.postalCode = this.getValueOrDefault(identityContent.zipOrPostalCode);
                        cipher.identity.country = this.getValueOrDefault(identityContent.countryOrRegion);
                        this.processIdentityItemUnmappedAndExtraFields(cipher, identityContent);
                        for (const extraField of item.data.extraFields) {
                            this.processKvp(cipher, extraField.fieldName, extraField.data.content, extraField.type === "hidden" ? FieldType.Hidden : FieldType.Text);
                        }
                        break;
                    }
                    default:
                        continue;
                }
                this.processFolder(result, vault.name);
                this.cleanupCipher(cipher);
                result.ciphers.push(cipher);
            }
        }
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/psono/psono-json-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore





class PsonoJsonImporter extends BaseImporter {
    constructor() {
        super(...arguments);
        this.WEBSITE_mappedValues = new Set([
            "type",
            "name",
            "website_password_title",
            "website_password_notes",
            "website_password_username",
            "website_password_password",
            "website_password_url",
            "autosubmit",
            "website_password_auto_submit",
            "urlfilter",
            "website_password_url_filter",
        ]);
        this.APP_PWD_mappedValues = new Set([
            "type",
            "name",
            "application_password_title",
            "application_password_notes",
            "application_password_username",
            "application_password_password",
        ]);
        this.BOOKMARK_mappedValues = new Set([
            "type",
            "name",
            "bookmark_title",
            "bookmark_notes",
            "bookmark_url",
        ]);
        this.NOTES_mappedValues = new Set(["type", "name", "note_title", "note_notes"]);
        this.TOTP_mappedValues = new Set(["type", "name", "totp_title", "totp_notes", "totp_code"]);
        this.ENV_VARIABLES_mappedValues = new Set([
            "type",
            "name",
            "environment_variables_title",
            "environment_variables_notes",
            "environment_variables_variables",
        ]);
        this.GPG_mappedValues = new Set([
            "type",
            "name",
            "mail_gpg_own_key_title",
            "mail_gpg_own_key_public",
            "mail_gpg_own_key_name",
            "mail_gpg_own_key_email",
            "mail_gpg_own_key_private",
        ]);
    }
    parse(data) {
        const result = new ImportResult();
        const psonoExport = JSON.parse(data);
        if (psonoExport == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        this.parseFolders(result, psonoExport.folders);
        this.handleItemParsing(result, psonoExport.items);
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
    parseFolders(result, folders, parentName) {
        if (folders == null || folders.length === 0) {
            return;
        }
        folders.forEach((folder) => {
            const folderHasItems = folder.items != null && folder.items.length > 0;
            const folderHasSubfolders = folder.folders != null && folder.folders.length > 0;
            if (!folderHasItems && !folderHasSubfolders) {
                return;
            }
            if (!utils_Utils.isNullOrWhitespace(parentName)) {
                folder.name = parentName + "/" + folder.name;
            }
            if (folderHasSubfolders) {
                this.parseFolders(result, folder.folders, folder.name);
            }
            if (!folderHasItems) {
                this.processFolder(result, folder.name, folderHasItems);
            }
            else {
                this.handleItemParsing(result, folder.items, folder.name);
            }
        });
    }
    handleItemParsing(result, items, folderName) {
        if (items == null || items.length === 0) {
            return;
        }
        items.forEach((record) => {
            const cipher = this.parsePsonoItem(record);
            this.processFolder(result, folderName, true);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
    }
    parsePsonoItem(item) {
        const cipher = this.initLoginCipher();
        switch (item.type) {
            case "website_password":
                this.parseWebsiteLogins(item, cipher);
                break;
            case "application_password":
                this.parseApplicationPasswords(item, cipher);
                break;
            case "environment_variables":
                this.parseEnvironmentVariables(item, cipher);
                break;
            case "totp":
                this.parseTOTP(item, cipher);
                break;
            case "bookmark":
                this.parseBookmarks(item, cipher);
                break;
            // Skipping this until we can save GPG into notes/custom fields
            // case "mail_gpg_own_key":
            //   this.parseGPG(item, cipher);
            //   break;
            case "note":
                this.parseNotes(item, cipher);
                break;
            default:
                break;
        }
        return cipher;
    }
    parseWebsiteLogins(entry, cipher) {
        var _a;
        if (entry == null || entry.type != "website_password") {
            return;
        }
        cipher.name = entry.website_password_title;
        cipher.notes = entry.website_password_notes;
        cipher.login.username = entry.website_password_username;
        cipher.login.password = entry.website_password_password;
        cipher.login.uris = this.makeUriArray(entry.website_password_url);
        this.processKvp(cipher, "website_password_auto_submit", (_a = entry.website_password_auto_submit) === null || _a === void 0 ? void 0 : _a.toString(), FieldType.Boolean);
        this.processKvp(cipher, "website_password_url_filter", entry.website_password_url_filter);
        this.importUnmappedFields(cipher, entry, this.WEBSITE_mappedValues);
    }
    parseApplicationPasswords(entry, cipher) {
        if (entry == null || entry.type != "application_password") {
            return;
        }
        cipher.name = entry.application_password_title;
        cipher.notes = entry.application_password_notes;
        cipher.login.username = entry.application_password_username;
        cipher.login.password = entry.application_password_password;
        this.importUnmappedFields(cipher, entry, this.APP_PWD_mappedValues);
    }
    parseBookmarks(entry, cipher) {
        if (entry == null || entry.type != "bookmark") {
            return;
        }
        cipher.name = entry.bookmark_title;
        cipher.notes = entry.bookmark_notes;
        cipher.login.uris = this.makeUriArray(entry.bookmark_url);
        this.importUnmappedFields(cipher, entry, this.BOOKMARK_mappedValues);
    }
    parseNotes(entry, cipher) {
        if (entry == null || entry.type != "note") {
            return;
        }
        cipher.type = CipherType.SecureNote;
        cipher.secureNote = new SecureNoteView();
        cipher.secureNote.type = SecureNoteType.Generic;
        cipher.name = entry.note_title;
        cipher.notes = entry.note_notes;
        this.importUnmappedFields(cipher, entry, this.NOTES_mappedValues);
    }
    parseTOTP(entry, cipher) {
        if (entry == null || entry.type != "totp") {
            return;
        }
        cipher.name = entry.totp_title;
        cipher.notes = entry.totp_notes;
        cipher.login.totp = entry.totp_code;
        this.importUnmappedFields(cipher, entry, this.TOTP_mappedValues);
    }
    parseEnvironmentVariables(entry, cipher) {
        if (entry == null || entry.type != "environment_variables") {
            return;
        }
        cipher.type = CipherType.SecureNote;
        cipher.secureNote = new SecureNoteView();
        cipher.secureNote.type = SecureNoteType.Generic;
        cipher.name = entry.environment_variables_title;
        cipher.notes = entry.environment_variables_notes;
        entry.environment_variables_variables.forEach((KvPair) => {
            this.processKvp(cipher, KvPair.key, KvPair.value);
        });
        this.importUnmappedFields(cipher, entry, this.ENV_VARIABLES_mappedValues);
    }
    parseGPG(entry, cipher) {
        if (entry == null || entry.type != "mail_gpg_own_key") {
            return;
        }
        cipher.type = CipherType.SecureNote;
        cipher.secureNote = new SecureNoteView();
        cipher.secureNote.type = SecureNoteType.Generic;
        cipher.name = entry.mail_gpg_own_key_title;
        cipher.notes = entry.mail_gpg_own_key_public;
        this.processKvp(cipher, "mail_gpg_own_key_name", entry.mail_gpg_own_key_name);
        this.processKvp(cipher, "mail_gpg_own_key_email", entry.mail_gpg_own_key_email);
        this.processKvp(cipher, "mail_gpg_own_key_private", entry.mail_gpg_own_key_private, FieldType.Hidden);
        this.importUnmappedFields(cipher, entry, this.GPG_mappedValues);
    }
    importUnmappedFields(cipher, entry, mappedValues) {
        const unmappedFields = Object.keys(entry).filter((x) => !mappedValues.has(x));
        unmappedFields.forEach((key) => {
            const item = entry;
            this.processKvp(cipher, key, item[key].toString());
        });
    }
}

;// ../../libs/importer/src/importers/remembear-csv-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore




class RememBearCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            if (value.trash === "true") {
                return;
            }
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(value.name);
            cipher.notes = this.getValueOrDefault(value.notes);
            if (value.type === "LoginItem") {
                cipher.login.uris = this.makeUriArray(value.website);
                cipher.login.password = this.getValueOrDefault(value.password);
                cipher.login.username = this.getValueOrDefault(value.username);
            }
            else if (value.type === "CreditCardItem") {
                cipher.type = CipherType.Card;
                cipher.card = new CardView();
                cipher.card.cardholderName = this.getValueOrDefault(value.cardholder);
                cipher.card.number = this.getValueOrDefault(value.number);
                cipher.card.brand = CardView.getCardBrandByPatterns(cipher.card.number);
                cipher.card.code = this.getValueOrDefault(value.verification);
                try {
                    const expMonth = this.getValueOrDefault(value.expiryMonth);
                    if (expMonth != null) {
                        const expMonthNumber = parseInt(expMonth, null);
                        if (expMonthNumber != null && expMonthNumber >= 1 && expMonthNumber <= 12) {
                            cipher.card.expMonth = expMonthNumber.toString();
                        }
                    }
                }
                catch (_a) {
                    // Ignore error
                }
                try {
                    const expYear = this.getValueOrDefault(value.expiryYear);
                    if (expYear != null) {
                        const expYearNumber = parseInt(expYear, null);
                        if (expYearNumber != null) {
                            cipher.card.expYear = expYearNumber.toString();
                        }
                    }
                }
                catch (_b) {
                    // Ignore error
                }
                const pin = this.getValueOrDefault(value.pin);
                if (pin != null) {
                    this.processKvp(cipher, "PIN", pin);
                }
                const zip = this.getValueOrDefault(value.zipCode);
                if (zip != null) {
                    this.processKvp(cipher, "Zip Code", zip);
                }
            }
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/roboform-csv-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore



class RoboFormCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        let i = 1;
        results.forEach((value) => {
            var _a, _b;
            const folder = !this.isNullOrWhitespace(value.Folder) && value.Folder.startsWith("/")
                ? value.Folder.replace("/", "")
                : value.Folder;
            const folderName = !this.isNullOrWhitespace(folder) ? folder : null;
            this.processFolder(result, folderName);
            const cipher = this.initLoginCipher();
            cipher.notes = this.getValueOrDefault(value.Note);
            cipher.name = this.getValueOrDefault(value.Name, "--");
            cipher.login.username = this.getValueOrDefault(value.Login);
            cipher.login.password =
                (_a = this.getValueOrDefault(value.Pwd)) !== null && _a !== void 0 ? _a : this.getValueOrDefault(value.Password);
            cipher.login.uris = (_b = this.makeUriArray(value.Url)) !== null && _b !== void 0 ? _b : this.makeUriArray(value.URL);
            if (!this.isNullOrWhitespace(value.Rf_fields)) {
                this.parseRfFields(cipher, value);
            }
            else if (!this.isNullOrWhitespace(value.RfFieldsV2)) {
                this.parseRfFieldsV2(cipher, value);
            }
            this.convertToNoteIfNeeded(cipher);
            this.cleanupCipher(cipher);
            if (i === results.length &&
                cipher.name === "--" &&
                this.isNullOrWhitespace(cipher.login.password)) {
                return;
            }
            result.ciphers.push(cipher);
            i++;
        });
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
    parseRfFields(cipher, value) {
        let fields = [value.Rf_fields];
        if (value.__parsed_extra != null && value.__parsed_extra.length > 0) {
            fields = fields.concat(value.__parsed_extra);
        }
        fields.forEach((field) => {
            const parts = field.split(":");
            if (parts.length < 3) {
                return;
            }
            const key = parts[0] === "-no-name-" ? null : parts[0];
            const val = parts.length === 4 && parts[2] === "rck" ? parts[1] : parts[2];
            this.processKvp(cipher, key, val);
        });
    }
    parseRfFieldsV2(cipher, value) {
        let fields = [value.RfFieldsV2];
        if (value.__parsed_extra != null && value.__parsed_extra.length > 0) {
            fields = fields.concat(value.__parsed_extra);
        }
        let userIdCount = 1;
        let passwordCount = 1;
        fields.forEach((field) => {
            const parts = field.split(",");
            if (parts.length < 5) {
                return;
            }
            const key = parts[0] === "-no-name-" ? null : parts[0];
            const type = parts[3] === "pwd" ? FieldType.Hidden : FieldType.Text;
            const val = parts[4];
            if (key === "TOTP KEY$") {
                cipher.login.totp = val;
                return;
            }
            // Skip if value matches login fields
            if (key === "User ID$" && val === cipher.login.username) {
                return;
            }
            if (key === "Password$" && val === cipher.login.password) {
                return;
            }
            // Index any extra User IDs or Passwords
            let displayKey = key;
            if (key === "User ID$") {
                displayKey = `Alternate User ID ${userIdCount++}`;
            }
            else if (key === "Password$") {
                displayKey = `Alternate Password ${passwordCount++}`;
            }
            this.processKvp(cipher, displayKey, val, type);
        });
    }
}

;// ../../libs/importer/src/importers/safari-csv-importer.ts


class SafariCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            var _a;
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(value.Title, "--");
            cipher.login.username = this.getValueOrDefault(value.Username);
            cipher.login.password = this.getValueOrDefault(value.Password);
            cipher.login.uris = this.makeUriArray((_a = value.Url) !== null && _a !== void 0 ? _a : value.URL);
            cipher.login.totp = this.getValueOrDefault(value.OTPAuth);
            cipher.notes = this.getValueOrDefault(value.Notes);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/safeincloud-xml-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore





class SafeInCloudXmlImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const doc = this.parseXml(data);
        if (doc == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        const db = doc.querySelector("database");
        if (db == null) {
            result.errorMessage = "Missing `database` node.";
            result.success = false;
            return Promise.resolve(result);
        }
        const foldersMap = new Map();
        Array.from(doc.querySelectorAll("database > label")).forEach((labelEl) => {
            const name = labelEl.getAttribute("name");
            const id = labelEl.getAttribute("id");
            if (!this.isNullOrWhitespace(name) && !this.isNullOrWhitespace(id)) {
                foldersMap.set(id, result.folders.length);
                const folder = new FolderView();
                folder.name = name;
                result.folders.push(folder);
            }
        });
        Array.from(doc.querySelectorAll("database > card")).forEach((cardEl) => {
            if (cardEl.getAttribute("template") === "true" || cardEl.getAttribute("deleted") === "true") {
                return;
            }
            const labelIdEl = this.querySelectorDirectChild(cardEl, "label_id");
            if (labelIdEl != null) {
                const labelId = labelIdEl.textContent;
                if (!this.isNullOrWhitespace(labelId) && foldersMap.has(labelId)) {
                    result.folderRelationships.push([result.ciphers.length, foldersMap.get(labelId)]);
                }
            }
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(cardEl.getAttribute("title"), "--");
            if (cardEl.getAttribute("star") === "true") {
                cipher.favorite = true;
            }
            const cardType = cardEl.getAttribute("type");
            if (cardType === "note") {
                cipher.type = CipherType.SecureNote;
                cipher.secureNote = new SecureNoteView();
                cipher.secureNote.type = SecureNoteType.Generic;
            }
            else {
                Array.from(this.querySelectorAllDirectChild(cardEl, "field")).forEach((fieldEl) => {
                    const text = fieldEl.textContent;
                    if (this.isNullOrWhitespace(text)) {
                        return;
                    }
                    const name = fieldEl.getAttribute("name");
                    const fieldType = this.getValueOrDefault(fieldEl.getAttribute("type"), "").toLowerCase();
                    if (fieldType === "login") {
                        cipher.login.username = text;
                    }
                    else if (fieldType === "password" || fieldType === "secret") {
                        // safeInCloud allows for more than one password. we just insert them here and find the one used as password later
                        this.processKvp(cipher, name, text, FieldType.Hidden);
                    }
                    else if (fieldType === "one_time_password") {
                        cipher.login.totp = text;
                    }
                    else if (fieldType === "notes") {
                        cipher.notes += text + "\n";
                    }
                    else if (fieldType === "weblogin" || fieldType === "website") {
                        cipher.login.uris.push(...this.makeUriArray(text));
                    }
                    else {
                        this.processKvp(cipher, name, text);
                    }
                });
            }
            Array.from(this.querySelectorAllDirectChild(cardEl, "notes")).forEach((notesEl) => {
                cipher.notes += notesEl.textContent + "\n";
            });
            this.setPassword(cipher);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
    // Choose a password from all passwords. Take one that has password in its name, or the first one if there is no such entry
    // if its name is password, we can safely remove it form the fields. otherwise, it would maybe be best to keep it as a hidden field
    setPassword(cipher) {
        const candidates = cipher.fields.filter((field) => field.type === FieldType.Hidden);
        if (!candidates.length) {
            return;
        }
        let choice;
        for (const field of candidates) {
            if (this.passwordFieldNames.includes(field.name.toLowerCase())) {
                choice = field;
                cipher.fields = cipher.fields.filter((f) => f !== choice);
                break;
            }
        }
        if (!choice) {
            choice = candidates[0];
        }
        cipher.login.password = choice.value;
    }
}

;// ../../libs/importer/src/importers/saferpass-csv-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


class SaferPassCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(this.nameFromUrl(value.url), "--");
            cipher.notes = this.getValueOrDefault(value.notes);
            cipher.login.username = this.getValueOrDefault(value.username);
            cipher.login.password = this.getValueOrDefault(value.password);
            cipher.login.uris = this.makeUriArray(value.url);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/securesafe-csv-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


class SecureSafeCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        // The url field can be in different case formats.
        const urlField = Object.keys(results[0]).find((k) => /url/i.test(k));
        results.forEach((value) => {
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(value.Title);
            cipher.notes = this.getValueOrDefault(value.Comment);
            cipher.login.uris = this.makeUriArray(value[urlField]);
            cipher.login.password = this.getValueOrDefault(value.Password);
            cipher.login.username = this.getValueOrDefault(value.Username);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/splashid-csv-importer.ts


class SplashIdCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, false);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            if (value.length < 3) {
                return;
            }
            this.processFolder(result, this.getValueOrDefault(value[value.length - 1]));
            const cipher = this.initLoginCipher();
            cipher.notes = this.getValueOrDefault(value[value.length - 2], "");
            cipher.name = this.getValueOrDefault(value[1], "--");
            if (value[0] === "Web Logins" || value[0] === "Servers" || value[0] === "Email Accounts") {
                cipher.login.username = this.getValueOrDefault(value[2]);
                cipher.login.password = this.getValueOrDefault(value[3]);
                cipher.login.uris = this.makeUriArray(value[4]);
                this.parseFieldsToNotes(cipher, 5, value);
            }
            else {
                this.parseFieldsToNotes(cipher, 2, value);
            }
            this.convertToNoteIfNeeded(cipher);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
    parseFieldsToNotes(cipher, startIndex, value) {
        // last 3 rows do not get parsed
        for (let i = startIndex; i < value.length - 3; i++) {
            if (this.isNullOrWhitespace(value[i])) {
                continue;
            }
            cipher.notes += value[i] + "\n";
        }
    }
}

;// ../../libs/importer/src/importers/stickypassword-xml-importer.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


class StickyPasswordXmlImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const doc = this.parseXml(data);
        if (doc == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        const loginNodes = doc.querySelectorAll("root > Database > Logins > Login");
        Array.from(loginNodes).forEach((loginNode) => {
            const accountId = loginNode.getAttribute("ID");
            if (this.isNullOrWhitespace(accountId)) {
                return;
            }
            const usernameText = loginNode.getAttribute("Name");
            const passwordText = loginNode.getAttribute("Password");
            let titleText = null;
            let linkText = null;
            let notesText = null;
            let groupId = null;
            let groupText = null;
            const accountLogin = doc.querySelector("root > Database > Accounts > Account > " +
                'LoginLinks > Login[SourceLoginID="' +
                accountId +
                '"]');
            if (accountLogin != null) {
                const account = accountLogin.parentElement.parentElement;
                if (account != null) {
                    titleText = account.getAttribute("Name");
                    linkText = account.getAttribute("Link");
                    groupId = account.getAttribute("ParentID");
                    notesText = account.getAttribute("Comments");
                    if (!this.isNullOrWhitespace(notesText)) {
                        notesText = notesText.split("/n").join("\n");
                    }
                }
            }
            if (!this.isNullOrWhitespace(groupId)) {
                groupText = this.buildGroupText(doc, groupId, "");
                this.processFolder(result, groupText);
            }
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(titleText, "--");
            cipher.notes = this.getValueOrDefault(notesText);
            cipher.login.username = this.getValueOrDefault(usernameText);
            cipher.login.password = this.getValueOrDefault(passwordText);
            cipher.login.uris = this.makeUriArray(linkText);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
    buildGroupText(doc, groupId, groupText) {
        const group = doc.querySelector('root > Database > Groups > Group[ID="' + groupId + '"]');
        if (group == null) {
            return groupText;
        }
        if (!this.isNullOrWhitespace(groupText)) {
            groupText = "/" + groupText;
        }
        groupText = group.getAttribute("Name") + groupText;
        return this.buildGroupText(doc, group.getAttribute("ParentID"), groupText);
    }
}

;// ../../libs/importer/src/importers/truekey-csv-importer.ts





const PropertiesToIgnore = [
    "kind",
    "autologin",
    "favorite",
    "hexcolor",
    "protectedwithpassword",
    "subdomainonly",
    "type",
    "tk_export_version",
    "note",
    "title",
    "document_content",
];
class TrueKeyCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            const cipher = this.initLoginCipher();
            cipher.favorite = this.getValueOrDefault(value.favorite, "").toLowerCase() === "true";
            cipher.name = this.getValueOrDefault(value.name, "--");
            cipher.notes = this.getValueOrDefault(value.memo, "");
            cipher.login.username = this.getValueOrDefault(value.login);
            cipher.login.password = this.getValueOrDefault(value.password);
            cipher.login.uris = this.makeUriArray(value.url);
            if (value.kind !== "login") {
                cipher.name = this.getValueOrDefault(value.title, "--");
                cipher.notes = this.getValueOrDefault(value.note, "");
            }
            if (value.kind === "cc") {
                cipher.type = CipherType.Card;
                cipher.card = new CardView();
                cipher.card.cardholderName = this.getValueOrDefault(value.cardholder);
                cipher.card.number = this.getValueOrDefault(value.number);
                cipher.card.brand = CardView.getCardBrandByPatterns(cipher.card.number);
                if (!this.isNullOrWhitespace(value.expiryDate)) {
                    try {
                        const expDate = new Date(value.expiryDate);
                        cipher.card.expYear = expDate.getFullYear().toString();
                        cipher.card.expMonth = (expDate.getMonth() + 1).toString();
                    }
                    catch (_a) {
                        // Ignore error
                    }
                }
            }
            else if (value.kind !== "login") {
                cipher.type = CipherType.SecureNote;
                cipher.secureNote = new SecureNoteView();
                cipher.secureNote.type = SecureNoteType.Generic;
                if (!this.isNullOrWhitespace(cipher.notes)) {
                    cipher.notes = this.getValueOrDefault(value.document_content, "");
                }
                for (const property in value) {
                    if (value.hasOwnProperty(property) && // eslint-disable-line
                        PropertiesToIgnore.indexOf(property.toLowerCase()) < 0 &&
                        !this.isNullOrWhitespace(value[property])) {
                        this.processKvp(cipher, property, value[property]);
                    }
                }
            }
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/upm-csv-importer.ts


class UpmCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, false);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            if (value.length !== 5) {
                return;
            }
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(value[0], "--");
            cipher.notes = this.getValueOrDefault(value[4]);
            cipher.login.username = this.getValueOrDefault(value[1]);
            cipher.login.password = this.getValueOrDefault(value[2]);
            cipher.login.uris = this.makeUriArray(value[3]);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/yoti-csv-importer.ts


class YotiCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            const cipher = this.initLoginCipher();
            cipher.name = this.getValueOrDefault(value.Name, "--");
            cipher.login.username = this.getValueOrDefault(value["User name"]);
            cipher.login.password = this.getValueOrDefault(value.Password);
            cipher.login.uris = this.makeUriArray(value.URL);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        result.success = true;
        return Promise.resolve(result);
    }
}

;// ../../libs/importer/src/importers/zohovault-csv-importer.ts


class ZohoVaultCsvImporter extends BaseImporter {
    parse(data) {
        const result = new ImportResult();
        const results = this.parseCsv(data, true);
        if (results == null) {
            result.success = false;
            return Promise.resolve(result);
        }
        results.forEach((value) => {
            if (this.isNullOrWhitespace(value["Password Name"]) &&
                this.isNullOrWhitespace(value["Secret Name"])) {
                return;
            }
            this.processFolder(result, this.getValueOrDefault(value["Folder Name"]));
            const cipher = this.initLoginCipher();
            cipher.favorite = this.getValueOrDefault(value.Favorite, "0") === "1";
            cipher.notes = this.getValueOrDefault(value.Notes);
            cipher.name = this.getValueOrDefault(value["Password Name"], this.getValueOrDefault(value["Secret Name"], "--"));
            cipher.login.uris = this.makeUriArray(this.getValueOrDefault(value["Password URL"], this.getValueOrDefault(value["Secret URL"])));
            cipher.login.totp = this.getValueOrDefault(value["login_totp"]);
            this.parseData(cipher, value.SecretData);
            this.parseData(cipher, value.CustomData);
            this.convertToNoteIfNeeded(cipher);
            this.cleanupCipher(cipher);
            result.ciphers.push(cipher);
        });
        if (this.organization) {
            this.moveFoldersToCollections(result);
        }
        result.success = true;
        return Promise.resolve(result);
    }
    parseData(cipher, data) {
        if (this.isNullOrWhitespace(data)) {
            return;
        }
        const dataLines = this.splitNewLine(data);
        dataLines.forEach((line) => {
            const delimPosition = line.indexOf(":");
            if (delimPosition < 0) {
                return;
            }
            const field = line.substring(0, delimPosition);
            const value = line.length > delimPosition ? line.substring(delimPosition + 1) : null;
            if (this.isNullOrWhitespace(field) ||
                this.isNullOrWhitespace(value) ||
                field === "SecretType") {
                return;
            }
            const fieldLower = field.toLowerCase();
            if (cipher.login.username == null && this.usernameFieldNames.indexOf(fieldLower) > -1) {
                cipher.login.username = value;
            }
            else if (cipher.login.password == null &&
                this.passwordFieldNames.indexOf(fieldLower) > -1) {
                cipher.login.password = value;
            }
            else {
                this.processKvp(cipher, field, value);
            }
        });
    }
}

;// ../../libs/importer/src/importers/index.ts
























































;// ../../libs/importer/src/models/import-options.ts
const featuredImportOptions = [
    { id: "bitwardenjson", name: "Bitwarden (json)" },
    { id: "bitwardencsv", name: "Bitwarden (csv)" },
    { id: "chromecsv", name: "Chrome" },
    { id: "dashlanecsv", name: "Dashlane (csv)" },
    { id: "firefoxcsv", name: "Firefox (csv)" },
    { id: "keepass2xml", name: "KeePass 2 (xml)" },
    { id: "lastpasscsv", name: "LastPass" },
    { id: "safaricsv", name: "Safari and macOS (csv)" },
    { id: "1password1pux", name: "1Password (1pux/json)" },
];
const regularImportOptions = [
    { id: "keepassxcsv", name: "KeePassX (csv)" },
    { id: "1password1pif", name: "1Password (1pif)" },
    { id: "1passwordwincsv", name: "1Password 6 and 7 Windows (csv)" },
    { id: "1passwordmaccsv", name: "1Password 6 and 7 Mac (csv)" },
    { id: "dashlanejson", name: "Dashlane (json)" },
    { id: "roboformcsv", name: "RoboForm (csv)" },
    { id: "keepercsv", name: "Keeper (csv)" },
    { id: "keeperjson", name: "Keeper (json)" },
    { id: "enpasscsv", name: "Enpass (csv)" },
    { id: "enpassjson", name: "Enpass (json)" },
    { id: "protonpass", name: "ProtonPass (zip/json)" },
    { id: "safeincloudxml", name: "SafeInCloud (xml)" },
    { id: "pwsafexml", name: "Password Safe - pwsafe.org (xml)" },
    { id: "stickypasswordxml", name: "Sticky Password (xml)" },
    { id: "msecurecsv", name: "mSecure (csv)" },
    { id: "truekeycsv", name: "True Key (csv)" },
    { id: "passwordbossjson", name: "Password Boss (json)" },
    { id: "zohovaultcsv", name: "Zoho Vault (csv)" },
    { id: "splashidcsv", name: "SplashID (csv)" },
    { id: "passworddragonxml", name: "Password Dragon (xml)" },
    { id: "padlockcsv", name: "Padlock (csv)" },
    { id: "passboltcsv", name: "Passbolt (csv)" },
    { id: "clipperzhtml", name: "Clipperz (html)" },
    { id: "aviracsv", name: "Avira (csv)" },
    { id: "saferpasscsv", name: "SaferPass (csv)" },
    { id: "upmcsv", name: "Universal Password Manager (csv)" },
    { id: "ascendocsv", name: "Ascendo DataVault (csv)" },
    { id: "meldiumcsv", name: "Meldium (csv)" },
    { id: "passkeepcsv", name: "PassKeep (csv)" },
    { id: "arccsv", name: "Arc" },
    { id: "edgecsv", name: "Edge" },
    { id: "operacsv", name: "Opera" },
    { id: "vivaldicsv", name: "Vivaldi" },
    { id: "bravecsv", name: "Brave" },
    { id: "gnomejson", name: "GNOME Passwords and Keys/Seahorse (json)" },
    { id: "blurcsv", name: "Blur (csv)" },
    { id: "passwordagentcsv", name: "Password Agent (csv)" },
    { id: "passpackcsv", name: "Passpack (csv)" },
    { id: "passmanjson", name: "Passman (json)" },
    { id: "avastcsv", name: "Avast Passwords (csv)" },
    { id: "avastjson", name: "Avast Passwords (json)" },
    { id: "fsecurefsk", name: "F-Secure KEY (fsk)" },
    { id: "kasperskytxt", name: "Kaspersky Password Manager (txt)" },
    { id: "remembearcsv", name: "RememBear (csv)" },
    { id: "passwordwallettxt", name: "PasswordWallet (txt)" },
    { id: "mykicsv", name: "Myki (csv)" },
    { id: "securesafecsv", name: "SecureSafe (csv)" },
    { id: "logmeoncecsv", name: "LogMeOnce (csv)" },
    { id: "blackberrycsv", name: "BlackBerry Password Keeper (csv)" },
    { id: "buttercupcsv", name: "Buttercup (csv)" },
    { id: "codebookcsv", name: "Codebook (csv)" },
    { id: "encryptrcsv", name: "Encryptr (csv)" },
    { id: "yoticsv", name: "Yoti (csv)" },
    { id: "nordpasscsv", name: "Nordpass (csv)" },
    { id: "psonojson", name: "Psono (json)" },
    { id: "passkyjson", name: "Passky (json)" },
    { id: "passwordxpcsv", name: "Password XP (csv)" },
    { id: "netwrixpasswordsecure", name: "Netwrix Password Secure (csv)" },
    { id: "passworddepot17xml", name: "Password Depot 17 (xml)" },
];

;// ../../libs/importer/src/services/import.service.ts
var import_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore

// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop.
// eslint-disable-next-line no-restricted-imports














class ImportService {
    constructor(cipherService, folderService, importApiService, i18nService, collectionService, keyService, encryptService, keyGenerationService, accountService, restrictedItemTypesService) {
        this.cipherService = cipherService;
        this.folderService = folderService;
        this.importApiService = importApiService;
        this.i18nService = i18nService;
        this.collectionService = collectionService;
        this.keyService = keyService;
        this.encryptService = encryptService;
        this.keyGenerationService = keyGenerationService;
        this.accountService = accountService;
        this.restrictedItemTypesService = restrictedItemTypesService;
        this.featuredImportOptions = featuredImportOptions;
        this.regularImportOptions = regularImportOptions;
    }
    getImportOptions() {
        return this.featuredImportOptions.concat(this.regularImportOptions);
    }
    import(importer_1, fileContents_1) {
        return import_service_awaiter(this, arguments, void 0, function* (importer, fileContents, organizationId = null, selectedImportTarget = null, canAccessImportExport) {
            let importResult;
            try {
                importResult = yield importer.parse(fileContents);
            }
            catch (error) {
                if (error instanceof SyntaxError) {
                    throw new Error(this.i18nService.t("importFormatError"));
                }
                throw error;
            }
            if (!importResult.success) {
                if (!utils_Utils.isNullOrWhitespace(importResult.errorMessage)) {
                    throw new Error(importResult.errorMessage);
                }
                throw new Error(this.i18nService.t("importFormatError"));
            }
            if (importResult.folders.length === 0 && importResult.ciphers.length === 0) {
                throw new Error(this.i18nService.t("importNothingError"));
            }
            if (importResult.ciphers.length > 0) {
                const halfway = Math.floor(importResult.ciphers.length / 2);
                const last = importResult.ciphers.length - 1;
                if (this.badData(importResult.ciphers[0]) &&
                    this.badData(importResult.ciphers[halfway]) &&
                    this.badData(importResult.ciphers[last])) {
                    throw new Error(this.i18nService.t("importFormatError"));
                }
            }
            const restrictedItemTypes = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.restrictedItemTypesService.restricted$.pipe((0,external_rxjs_namespaceObject.map)((restrictedItemTypes) => restrictedItemTypes.map((r) => r.cipherType))));
            // Filter out restricted item types from the import result
            importResult.ciphers = importResult.ciphers.filter((cipher) => !restrictedItemTypes.includes(cipher.type));
            if (organizationId && !selectedImportTarget && !canAccessImportExport) {
                const hasUnassignedCollections = importResult.collectionRelationships.length < importResult.ciphers.length;
                if (hasUnassignedCollections) {
                    throw new Error(this.i18nService.t("importUnassignedItemsError"));
                }
            }
            try {
                yield this.setImportTarget(importResult, organizationId, selectedImportTarget);
                const userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe(account_service_getUserId));
                if (organizationId != null) {
                    yield this.handleOrganizationalImport(importResult, organizationId, userId);
                }
                else {
                    yield this.handleIndividualImport(importResult, userId);
                }
            }
            catch (error) {
                const errorResponse = new ErrorResponse(error, 400);
                throw this.handleServerError(errorResponse, importResult);
            }
            return importResult;
        });
    }
    getImporter(format, promptForPassword_callback, organizationId = null) {
        if (promptForPassword_callback == null) {
            return null;
        }
        const importer = this.getImporterInstance(format, promptForPassword_callback);
        if (importer == null) {
            return null;
        }
        importer.organizationId = organizationId;
        return importer;
    }
    getImporterInstance(format, promptForPassword_callback) {
        if (format == null) {
            return null;
        }
        switch (format) {
            case "bitwardencsv":
                return new BitwardenCsvImporter();
            case "bitwardenjson":
            case "bitwardenpasswordprotected":
                return new BitwardenPasswordProtectedImporter(this.keyService, this.encryptService, this.i18nService, this.cipherService, this.keyGenerationService, this.accountService, promptForPassword_callback);
            case "lastpasscsv":
            case "passboltcsv":
                return new LastPassCsvImporter();
            case "keepassxcsv":
                return new KeePassXCsvImporter();
            case "aviracsv":
                return new AviraCsvImporter();
            case "blurcsv":
                return new BlurCsvImporter();
            case "safeincloudxml":
                return new SafeInCloudXmlImporter();
            case "padlockcsv":
                return new PadlockCsvImporter();
            case "keepass2xml":
                return new KeePass2XmlImporter();
            case "arccsv":
                return new ArcCsvImporter();
            case "edgecsv":
            case "chromecsv":
            case "operacsv":
            case "vivaldicsv":
            case "bravecsv":
                return new ChromeCsvImporter();
            case "firefoxcsv":
                return new FirefoxCsvImporter();
            case "upmcsv":
                return new UpmCsvImporter();
            case "saferpasscsv":
                return new SaferPassCsvImporter();
            case "safaricsv":
                return new SafariCsvImporter();
            case "meldiumcsv":
                return new MeldiumCsvImporter();
            case "1password1pif":
                return new OnePassword1PifImporter();
            case "1password1pux":
                return new OnePassword1PuxImporter();
            case "1passwordwincsv":
                return new OnePasswordWinCsvImporter();
            case "1passwordmaccsv":
                return new OnePasswordMacCsvImporter();
            case "keepercsv":
                return new KeeperCsvImporter();
            case "keeperjson":
                return new KeeperJsonImporter();
            case "passworddragonxml":
                return new PasswordDragonXmlImporter();
            case "enpasscsv":
                return new EnpassCsvImporter();
            case "enpassjson":
                return new EnpassJsonImporter();
            case "pwsafexml":
                return new PasswordSafeXmlImporter();
            case "dashlanecsv":
                return new DashlaneCsvImporter();
            case "dashlanejson":
                return new DashlaneJsonImporter();
            case "msecurecsv":
                return new MSecureCsvImporter();
            case "stickypasswordxml":
                return new StickyPasswordXmlImporter();
            case "truekeycsv":
                return new TrueKeyCsvImporter();
            case "clipperzhtml":
                return new ClipperzHtmlImporter();
            case "roboformcsv":
                return new RoboFormCsvImporter();
            case "ascendocsv":
                return new AscendoCsvImporter();
            case "passwordbossjson":
                return new PasswordBossJsonImporter();
            case "zohovaultcsv":
                return new ZohoVaultCsvImporter();
            case "splashidcsv":
                return new SplashIdCsvImporter();
            case "passkeepcsv":
                return new PassKeepCsvImporter();
            case "gnomejson":
                return new GnomeJsonImporter();
            case "passwordagentcsv":
                return new PasswordAgentCsvImporter();
            case "passpackcsv":
                return new PasspackCsvImporter();
            case "passmanjson":
                return new PassmanJsonImporter();
            case "avastcsv":
                return new AvastCsvImporter();
            case "avastjson":
                return new AvastJsonImporter();
            case "fsecurefsk":
                return new FSecureFskImporter();
            case "kasperskytxt":
                return new KasperskyTxtImporter();
            case "remembearcsv":
                return new RememBearCsvImporter();
            case "passwordwallettxt":
                return new PasswordWalletTxtImporter();
            case "mykicsv":
                return new MykiCsvImporter();
            case "securesafecsv":
                return new SecureSafeCsvImporter();
            case "logmeoncecsv":
                return new LogMeOnceCsvImporter();
            case "blackberrycsv":
                return new BlackBerryCsvImporter();
            case "buttercupcsv":
                return new ButtercupCsvImporter();
            case "codebookcsv":
                return new CodebookCsvImporter();
            case "encryptrcsv":
                return new EncryptrCsvImporter();
            case "yoticsv":
                return new YotiCsvImporter();
            case "nordpasscsv":
                return new NordPassCsvImporter();
            case "psonojson":
                return new PsonoJsonImporter();
            case "passkyjson":
                return new PasskyJsonImporter();
            case "protonpass":
                return new ProtonPassJsonImporter(this.i18nService);
            case "passwordxpcsv":
                return new PasswordXPCsvImporter();
            case "netwrixpasswordsecure":
                return new NetwrixPasswordSecureCsvImporter();
            case "passworddepot17xml":
                return new PasswordDepot17XmlImporter();
            default:
                return null;
        }
    }
    handleIndividualImport(importResult, userId) {
        return import_service_awaiter(this, void 0, void 0, function* () {
            const request = new ImportCiphersRequest();
            const encryptedCiphers = yield this.cipherService.encryptMany(importResult.ciphers, userId);
            for (const encryptedCipher of encryptedCiphers) {
                request.ciphers.push(new CipherRequest(encryptedCipher));
            }
            const userKey = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.keyService.userKey$(userId));
            if (importResult.folders != null) {
                for (let i = 0; i < importResult.folders.length; i++) {
                    const f = yield this.folderService.encrypt(importResult.folders[i], userKey);
                    request.folders.push(new FolderWithOptionalIdRequest(f));
                }
            }
            if (importResult.folderRelationships != null) {
                importResult.folderRelationships.forEach((r) => request.folderRelationships.push(new KvpRequest(r[0], r[1])));
            }
            return yield this.importApiService.postImportCiphers(request);
        });
    }
    handleOrganizationalImport(importResult, organizationId, userId) {
        return import_service_awaiter(this, void 0, void 0, function* () {
            const request = new ImportOrganizationCiphersRequest();
            // Set organization ID on all ciphers before batch encryption
            importResult.ciphers.forEach((cipher) => {
                cipher.organizationId = organizationId;
            });
            const encryptedCiphers = yield this.cipherService.encryptMany(importResult.ciphers, userId);
            for (const encryptedCipher of encryptedCiphers) {
                request.ciphers.push(new CipherRequest(encryptedCipher));
            }
            if (importResult.collections != null) {
                for (let i = 0; i < importResult.collections.length; i++) {
                    importResult.collections[i].organizationId = organizationId;
                    const c = yield this.collectionService.encrypt(importResult.collections[i], userId);
                    request.collections.push(new CollectionWithIdRequest(c));
                }
            }
            if (importResult.collectionRelationships != null) {
                importResult.collectionRelationships.forEach((r) => request.collectionRelationships.push(new KvpRequest(r[0], r[1])));
            }
            return yield this.importApiService.postImportOrganizationCiphers(organizationId, request);
        });
    }
    badData(c) {
        return ((c.name == null || c.name === "--") &&
            c.type === CipherType.Login &&
            c.login != null &&
            utils_Utils.isNullOrWhitespace(c.login.password));
    }
    handleServerError(errorResponse, importResult) {
        if (errorResponse.validationErrors == null) {
            return new Error(errorResponse.message);
        }
        let errorMessage = "";
        Object.entries(errorResponse.validationErrors).forEach(([key, value], index) => {
            let item;
            let itemType;
            const i = Number(key.match(/[0-9]+/)[0]);
            switch (key.match(/^\w+/)[0]) {
                case "Ciphers":
                    item = importResult.ciphers[i];
                    itemType = toCipherTypeName(item.type);
                    break;
                case "Folders":
                    item = importResult.folders[i];
                    itemType = "Folder";
                    break;
                case "Collections":
                    item = importResult.collections[i];
                    itemType = "Collection";
                    break;
                default:
                    return;
            }
            if (index > 0) {
                errorMessage += "\n\n";
            }
            if (itemType !== "Folder" && itemType !== "Collection") {
                errorMessage += "[" + (i + 1) + "] ";
            }
            errorMessage += "[" + itemType + '] "' + item.name + '": ' + value;
        });
        return new Error(errorMessage);
    }
    setImportTarget(importResult, organizationId, importTarget) {
        return import_service_awaiter(this, void 0, void 0, function* () {
            if (!importTarget) {
                return;
            }
            // Importing into an organization
            if (organizationId) {
                if (!(importTarget instanceof CollectionView)) {
                    throw new Error(this.i18nService.t("errorAssigningTargetCollection"));
                }
                const noCollectionRelationShips = [];
                importResult.ciphers.forEach((c, index) => {
                    if (!Array.isArray(importResult.collectionRelationships) ||
                        !importResult.collectionRelationships.some(([cipherPos]) => cipherPos === index)) {
                        noCollectionRelationShips.push([index, 0]);
                    }
                });
                // My Items collections do not support collection nesting.
                // Flatten all ciphers from nested collections into the import target.
                if (importTarget.type === CollectionTypes.DefaultUserCollection) {
                    importResult.collections = [importTarget];
                    const flattenRelationships = [];
                    importResult.ciphers.forEach((c, index) => {
                        flattenRelationships.push([index, 0]);
                    });
                    importResult.collectionRelationships = flattenRelationships;
                    return;
                }
                const collections = [...importResult.collections];
                importResult.collections = [importTarget];
                collections.map((x) => {
                    const f = new CollectionView(x);
                    f.name = `${importTarget.name}/${x.name}`;
                    importResult.collections.push(f);
                });
                const relationships = [...importResult.collectionRelationships];
                importResult.collectionRelationships = [...noCollectionRelationShips];
                relationships.map((x) => {
                    importResult.collectionRelationships.push([x[0], x[1] + 1]);
                });
                return;
            }
            // Importing into personal vault
            if (!(importTarget instanceof FolderView)) {
                throw new Error(this.i18nService.t("errorAssigningTargetFolder"));
            }
            const noFolderRelationShips = [];
            importResult.ciphers.forEach((c, index) => {
                if (utils_Utils.isNullOrEmpty(c.folderId)) {
                    c.folderId = importTarget.id;
                    noFolderRelationShips.push([index, 0]);
                }
            });
            const folders = [...importResult.folders];
            importResult.folders = [importTarget];
            folders.map((x) => {
                const newFolderName = `${importTarget.name}/${x.name}`;
                const f = new FolderView();
                f.name = newFolderName;
                importResult.folders.push(f);
            });
            const relationships = [...importResult.folderRelationships];
            importResult.folderRelationships = [...noFolderRelationShips];
            relationships.map((x) => {
                importResult.folderRelationships.push([x[0], x[1] + 1]);
            });
        });
    }
}

;// ../../libs/importer/src/util.ts

/** Lookup the loaders supported by a specific client.
 *  WARNING: this method does not supply metadata for every import type.
 *  @returns `undefined` when metadata is not defined for the type, or
 *   an array identifying the supported clients.
 */
function availableLoaders(importersMetadata, type, client) {
    var _a, _b;
    if (!importersMetadata) {
        return undefined;
    }
    if (!(type in importersMetadata)) {
        return undefined;
    }
    const capabilities = (_b = (_a = importersMetadata[type]) === null || _a === void 0 ? void 0 : _a.loaders) !== null && _b !== void 0 ? _b : [];
    const available = capabilities.filter((loader) => LoaderAvailability[loader].includes(client));
    return available;
}

;// ../../libs/importer/src/services/default-import-metadata.service.ts
var default_import_metadata_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};



class DefaultImportMetadataService {
    constructor(system) {
        this.system = system;
        this.importers = Importers;
        this.logger = system.log({ type: "ImportMetadataService" });
    }
    init() {
        return default_import_metadata_service_awaiter(this, void 0, void 0, function* () {
            // no-op for default implementation
        });
    }
    metadata$(type$) {
        const client = this.system.environment.getClientType();
        const capabilities$ = type$.pipe((0,external_rxjs_namespaceObject.map)((type) => {
            var _a;
            if (!this.importers) {
                return { type, loaders: [] };
            }
            const loaders = availableLoaders(this.importers, type, client);
            if (!loaders || loaders.length === 0) {
                return { type, loaders: [] };
            }
            const capabilities = { type, loaders };
            if (type in this.importers) {
                capabilities.instructions = (_a = this.importers[type]) === null || _a === void 0 ? void 0 : _a.instructions;
            }
            this.logger.debug({ importType: type, capabilities }, "capabilities updated");
            return capabilities;
        }));
        return capabilities$;
    }
}

;// ../../libs/importer/src/services/index.ts








;// ../../libs/importer/src/index.ts




;// external "crypto"
const external_crypto_namespaceObject = require("crypto");
;// ../../libs/node/src/services/node-crypto-function.service.ts
var node_crypto_function_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};




class NodeCryptoFunctionService {
    pbkdf2(password, salt, algorithm, iterations) {
        const len = algorithm === "sha256" ? 32 : 64;
        return new Promise((resolve, reject) => {
            external_crypto_namespaceObject.pbkdf2(password, salt, iterations, len, algorithm, (error, key) => {
                if (error != null) {
                    reject(error);
                }
                else {
                    resolve(new Uint8Array(key));
                }
            });
        });
    }
    // ref: https://tools.ietf.org/html/rfc5869
    hkdf(ikm, salt, info, outputByteSize, algorithm) {
        return node_crypto_function_service_awaiter(this, void 0, void 0, function* () {
            const saltArr = typeof salt === "string" ? utils_Utils.fromUtf8ToArray(salt) : salt;
            const prk = yield this.hmac(ikm, saltArr, algorithm);
            return this.hkdfExpand(prk, info, outputByteSize, algorithm);
        });
    }
    // ref: https://tools.ietf.org/html/rfc5869
    hkdfExpand(prk, info, outputByteSize, algorithm) {
        return node_crypto_function_service_awaiter(this, void 0, void 0, function* () {
            const hashLen = algorithm === "sha256" ? 32 : 64;
            if (outputByteSize > 255 * hashLen) {
                throw new Error("outputByteSize is too large.");
            }
            const prkArr = new Uint8Array(prk);
            if (prkArr.length < hashLen) {
                throw new Error("prk is too small.");
            }
            const infoBuf = typeof info === "string" ? utils_Utils.fromUtf8ToArray(info) : info;
            const infoArr = new Uint8Array(infoBuf);
            let runningOkmLength = 0;
            let previousT = new Uint8Array(0);
            const n = Math.ceil(outputByteSize / hashLen);
            const okm = new Uint8Array(n * hashLen);
            for (let i = 0; i < n; i++) {
                const t = new Uint8Array(previousT.length + infoArr.length + 1);
                t.set(previousT);
                t.set(infoArr, previousT.length);
                t.set([i + 1], t.length - 1);
                previousT = yield this.hmac(t, prk, algorithm);
                okm.set(previousT, runningOkmLength);
                runningOkmLength += previousT.length;
                if (runningOkmLength >= outputByteSize) {
                    break;
                }
            }
            return okm.slice(0, outputByteSize);
        });
    }
    hash(value, algorithm) {
        const hash = external_crypto_namespaceObject.createHash(algorithm);
        hash.update(value);
        return Promise.resolve(new Uint8Array(hash.digest()));
    }
    rsaEncrypt(data, publicKey, _algorithm) {
        return node_crypto_function_service_awaiter(this, void 0, void 0, function* () {
            yield SdkLoadService.Ready;
            return bitwarden_wasm_internal_bg/* PureCrypto */.IEs.rsa_encrypt_data(data, publicKey);
        });
    }
    rsaDecrypt(data, privateKey, _algorithm) {
        return node_crypto_function_service_awaiter(this, void 0, void 0, function* () {
            yield SdkLoadService.Ready;
            return bitwarden_wasm_internal_bg/* PureCrypto */.IEs.rsa_decrypt_data(data, privateKey);
        });
    }
    rsaExtractPublicKey(privateKey) {
        return node_crypto_function_service_awaiter(this, void 0, void 0, function* () {
            yield SdkLoadService.Ready;
            return bitwarden_wasm_internal_bg/* PureCrypto */.IEs.rsa_extract_public_key(privateKey);
        });
    }
    rsaGenerateKeyPair(_length) {
        return node_crypto_function_service_awaiter(this, void 0, void 0, function* () {
            yield SdkLoadService.Ready;
            const privateKey = bitwarden_wasm_internal_bg/* PureCrypto */.IEs.rsa_generate_keypair();
            const publicKey = yield this.rsaExtractPublicKey(privateKey);
            return [publicKey, privateKey];
        });
    }
    aesGenerateKey(bitLength) {
        return this.randomBytes(bitLength / 8);
    }
    randomBytes(length) {
        return new Promise((resolve, reject) => {
            external_crypto_namespaceObject.randomBytes(length, (error, bytes) => {
                if (error != null) {
                    reject(error);
                }
                else {
                    resolve(new Uint8Array(bytes));
                }
            });
        });
    }
    hmac(value, key, algorithm) {
        const hmac = external_crypto_namespaceObject.createHmac(algorithm, key);
        hmac.update(value);
        return Promise.resolve(new Uint8Array(hmac.digest()));
    }
}

;// ../../libs/unlock/src/default-unlock.service.ts
var default_unlock_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var default_unlock_service_addDisposableResource = (undefined && undefined.__addDisposableResource) || function (env, value, async) {
    if (value !== null && value !== void 0) {
        if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
        var dispose, inner;
        if (async) {
            if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
            dispose = value[Symbol.asyncDispose];
        }
        if (dispose === void 0) {
            if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
            dispose = value[Symbol.dispose];
            if (async) inner = dispose;
        }
        if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
        if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
        env.stack.push({ value: value, dispose: dispose, async: async });
    }
    else if (async) {
        env.stack.push({ async: true });
    }
    return value;
};
var default_unlock_service_disposeResources = (undefined && undefined.__disposeResources) || (function (SuppressedError) {
    return function (env) {
        function fail(e) {
            env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
            env.hasError = true;
        }
        var r, s = 0;
        function next() {
            while (r = env.stack.pop()) {
                try {
                    if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
                    if (r.dispose) {
                        var result = r.dispose.call(r.value);
                        if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
                    }
                    else s |= 1;
                }
                catch (e) {
                    fail(e);
                }
            }
            if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
            if (env.hasError) throw env.error;
        }
        return next();
    };
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
    var e = new Error(message);
    return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
});










class DefaultUnlockService {
    constructor(registerSdkService, accountCryptographicStateService, pinStateService, kdfService, accountService, masterPasswordService, stateProvider, logService, biometricsService, platformUtilsService, stateService, biometricStateService) {
        this.registerSdkService = registerSdkService;
        this.accountCryptographicStateService = accountCryptographicStateService;
        this.pinStateService = pinStateService;
        this.kdfService = kdfService;
        this.accountService = accountService;
        this.masterPasswordService = masterPasswordService;
        this.stateProvider = stateProvider;
        this.logService = logService;
        this.biometricsService = biometricsService;
        this.platformUtilsService = platformUtilsService;
        this.stateService = stateService;
        this.biometricStateService = biometricStateService;
    }
    unlockWithPin(userId, pin) {
        return default_unlock_service_awaiter(this, void 0, void 0, function* () {
            const startTime = performance.now();
            yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.registerSdkService.registerClient$(userId).pipe((0,external_rxjs_namespaceObject.map)((sdk) => default_unlock_service_awaiter(this, void 0, void 0, function* () {
                const env_1 = { stack: [], error: void 0, hasError: false };
                try {
                    if (!sdk) {
                        throw new Error("SDK not available");
                    }
                    const ref = default_unlock_service_addDisposableResource(env_1, sdk.take(), false);
                    yield ref.value.crypto().initialize_user_crypto({
                        userId: asUuid(userId),
                        kdfParams: yield this.getKdfParams(userId),
                        email: yield this.getEmail(userId),
                        accountCryptographicState: yield this.getAccountCryptographicState(userId),
                        method: {
                            pinEnvelope: {
                                pin: pin,
                                pin_protected_user_key_envelope: yield this.getPinProtectedUserKeyEnvelope(userId),
                            },
                        },
                    });
                    yield this.runOnUnlockSideEffects(userId, ref);
                }
                catch (e_1) {
                    env_1.error = e_1;
                    env_1.hasError = true;
                }
                finally {
                    default_unlock_service_disposeResources(env_1);
                }
            }))));
            this.logService.measure(startTime, "Unlock", "DefaultUnlockService", "unlockWithPin");
        });
    }
    unlockWithMasterPassword(userId, masterPassword) {
        return default_unlock_service_awaiter(this, void 0, void 0, function* () {
            const startTime = performance.now();
            yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.registerSdkService.registerClient$(userId).pipe((0,external_rxjs_namespaceObject.map)((sdk) => default_unlock_service_awaiter(this, void 0, void 0, function* () {
                const env_2 = { stack: [], error: void 0, hasError: false };
                try {
                    if (!sdk) {
                        throw new Error("SDK not available");
                    }
                    const ref = default_unlock_service_addDisposableResource(env_2, sdk.take(), false);
                    yield ref.value.crypto().initialize_user_crypto({
                        userId: asUuid(userId),
                        kdfParams: yield this.getKdfParams(userId),
                        email: yield this.getEmail(userId),
                        accountCryptographicState: yield this.getAccountCryptographicState(userId),
                        method: {
                            masterPasswordUnlock: {
                                password: masterPassword,
                                master_password_unlock: yield this.getMasterPasswordUnlockData(userId),
                            },
                        },
                    });
                    yield this.runOnUnlockSideEffects(userId, ref);
                }
                catch (e_2) {
                    env_2.error = e_2;
                    env_2.hasError = true;
                }
                finally {
                    default_unlock_service_disposeResources(env_2);
                }
            }))));
            yield this.setLegacyMasterKeyFromUnlockData(masterPassword, yield this.getMasterPasswordUnlockData(userId), userId);
            this.logService.measure(startTime, "Unlock", "DefaultUnlockService", "unlockWithMasterPassword");
        });
    }
    unlockWithBiometrics(userId) {
        return default_unlock_service_awaiter(this, void 0, void 0, function* () {
            // First, get the biometrics-protected user key. This will prompt the user to authenticate with biometrics.
            const userKey = yield this.biometricsService.unlockWithBiometricsForUser(userId);
            if (!userKey) {
                throw new Error("Failed to unlock with biometrics");
            }
            // Now that we have the biometrics-protected user key, we can initialize the SDK with it to complete the unlock process.
            const startTime = performance.now();
            yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.registerSdkService.registerClient$(userId).pipe((0,external_rxjs_namespaceObject.map)((sdk) => default_unlock_service_awaiter(this, void 0, void 0, function* () {
                const env_3 = { stack: [], error: void 0, hasError: false };
                try {
                    if (!sdk) {
                        throw new Error("SDK not available");
                    }
                    const ref = default_unlock_service_addDisposableResource(env_3, sdk.take(), false);
                    yield ref.value.crypto().initialize_user_crypto({
                        userId: asUuid(userId),
                        kdfParams: yield this.getKdfParams(userId),
                        email: yield this.getEmail(userId),
                        accountCryptographicState: yield this.getAccountCryptographicState(userId),
                        method: {
                            decryptedKey: {
                                decrypted_user_key: userKey.toBase64(),
                            },
                        },
                    });
                    yield this.runOnUnlockSideEffects(userId, ref);
                }
                catch (e_3) {
                    env_3.error = e_3;
                    env_3.hasError = true;
                }
                finally {
                    default_unlock_service_disposeResources(env_3);
                }
            }))));
            this.logService.measure(startTime, "Unlock", "DefaultUnlockService", "unlockWithBiometrics");
        });
    }
    unlockWithKeyConnector(userId, keyConnectorUnlockData) {
        return default_unlock_service_awaiter(this, void 0, void 0, function* () {
            // The SDK is responsible for fetching the key-connector-key from the key-connector using the
            // key-connector-unlock-data. It will unwrap the provided key and set it to state, unlocking
            // the vault.
            const startTime = performance.now();
            yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.registerSdkService.registerClient$(userId).pipe((0,external_rxjs_namespaceObject.map)((sdk) => default_unlock_service_awaiter(this, void 0, void 0, function* () {
                const env_4 = { stack: [], error: void 0, hasError: false };
                try {
                    if (!sdk) {
                        throw new Error("SDK not available");
                    }
                    const ref = default_unlock_service_addDisposableResource(env_4, sdk.take(), false);
                    return ref.value.crypto().initialize_user_crypto({
                        userId: asUuid(userId),
                        kdfParams: yield this.getKdfParams(userId),
                        email: yield this.getEmail(userId),
                        accountCryptographicState: yield this.getAccountCryptographicState(userId),
                        method: {
                            keyConnectorUrl: {
                                url: keyConnectorUnlockData.url,
                                key_connector_key_wrapped_user_key: keyConnectorUnlockData.keyConnectorKeyWrappedUserKey,
                            },
                        },
                    });
                }
                catch (e_4) {
                    env_4.error = e_4;
                    env_4.hasError = true;
                }
                finally {
                    default_unlock_service_disposeResources(env_4);
                }
            }))));
            this.logService.measure(startTime, "Unlock", "DefaultUnlockService", "unlockWithKeyConnector");
        });
    }
    getAccountCryptographicState(userId) {
        return default_unlock_service_awaiter(this, void 0, void 0, function* () {
            const accountCryptographicState = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountCryptographicStateService.accountCryptographicState$(userId));
            assertNonNullish(accountCryptographicState, "Account cryptographic state is required");
            return accountCryptographicState;
        });
    }
    getKdfParams(userId) {
        return default_unlock_service_awaiter(this, void 0, void 0, function* () {
            const kdfParams = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.kdfService.getKdfConfig$(userId).pipe((0,external_rxjs_namespaceObject.map)((config) => {
                return config === null || config === void 0 ? void 0 : config.toSdkConfig();
            })));
            assertNonNullish(kdfParams, "KDF parameters are required");
            return kdfParams;
        });
    }
    getEmail(userId) {
        return default_unlock_service_awaiter(this, void 0, void 0, function* () {
            const accounts = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.accounts$);
            const email = accounts[userId].email;
            assertNonNullish(email, "Email is required");
            return email;
        });
    }
    getPinProtectedUserKeyEnvelope(userId) {
        return default_unlock_service_awaiter(this, void 0, void 0, function* () {
            const pinLockType = yield this.pinStateService.getPinLockType(userId);
            const pinEnvelope = yield this.pinStateService.getPinProtectedUserKeyEnvelope(userId, pinLockType);
            assertNonNullish(pinEnvelope, "User is not enrolled in PIN unlock");
            return pinEnvelope;
        });
    }
    getMasterPasswordUnlockData(userId) {
        return default_unlock_service_awaiter(this, void 0, void 0, function* () {
            const unlockData = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.masterPasswordService.masterPasswordUnlockData$(userId));
            assertNonNullish(unlockData, "Master password unlock data is required");
            return unlockData.toSdk();
        });
    }
    setLegacyMasterKeyFromUnlockData(password, masterPasswordUnlockData, userId) {
        return default_unlock_service_awaiter(this, void 0, void 0, function* () {
            assertNonNullish(password, "password");
            assertNonNullish(masterPasswordUnlockData, "masterPasswordUnlockData");
            assertNonNullish(userId, "userId");
            this.logService.info("[DefaultUnlockService] Setting legacy master key from unlock data");
            // NOTE: This entire section is deprecated and will be removed as soon as
            // the masterkey is dropped from state. It is very temporary.
            yield SdkLoadService.Ready;
            const passwordBuffer = new TextEncoder().encode(password);
            const saltBuffer = new TextEncoder().encode(masterPasswordUnlockData.salt);
            const masterKey = bitwarden_wasm_internal_bg/* PureCrypto */.IEs.derive_kdf_material(passwordBuffer, saltBuffer, masterPasswordUnlockData.kdf);
            yield this.stateProvider
                .getUser(userId, MASTER_KEY)
                .update((_) => new SymmetricCryptoKey(masterKey));
        });
    }
    // When unlocking, certain side-effects must be run, such as setting the never-lock key and the biometrics key.
    // Currently this does not happen from within the SDK but form here instead.
    runOnUnlockSideEffects(userId, client) {
        return default_unlock_service_awaiter(this, void 0, void 0, function* () {
            const userKey = SymmetricCryptoKey.fromString(yield client.value.crypto().get_user_encryption_key());
            if (yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.biometricStateService.biometricUnlockEnabled$(userId))) {
                yield this.biometricsService.setBiometricProtectedUnlockKeyForUser(userId, userKey);
            }
            if (yield this.shouldStoreUserKeyAutoUnlock(userId)) {
                yield this.stateService.setUserKeyAutoUnlock(userKey.toBase64(), { userId: userId });
            }
            yield this.stateProvider.setUserState(user_key_state_USER_EVER_HAD_USER_KEY, true, userId);
        });
    }
    shouldStoreUserKeyAutoUnlock(userId) {
        return default_unlock_service_awaiter(this, void 0, void 0, function* () {
            if (this.platformUtilsService.getClientType() === src_ClientType.Cli) {
                return true;
            }
            const vaultTimeout = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.stateProvider
                .getUserState$(vault_timeout_settings_state_VAULT_TIMEOUT, userId)
                .pipe((0,external_rxjs_namespaceObject.filter)((timeout) => timeout != null)));
            return vaultTimeout == VaultTimeoutStringType.Never;
        });
    }
}

;// ../../libs/unlock/src/index.ts



;// ./src/key-management/cli-biometrics-service.ts
var cli_biometrics_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

class CliBiometricsService extends BiometricsService {
    authenticateWithBiometrics() {
        return cli_biometrics_service_awaiter(this, void 0, void 0, function* () {
            return false;
        });
    }
    getBiometricsStatus() {
        return cli_biometrics_service_awaiter(this, void 0, void 0, function* () {
            return BiometricsStatus.PlatformUnsupported;
        });
    }
    unlockWithBiometricsForUser(userId) {
        return cli_biometrics_service_awaiter(this, void 0, void 0, function* () {
            return null;
        });
    }
    getBiometricsStatusForUser(userId) {
        return cli_biometrics_service_awaiter(this, void 0, void 0, function* () {
            return BiometricsStatus.PlatformUnsupported;
        });
    }
    getShouldAutopromptNow() {
        return cli_biometrics_service_awaiter(this, void 0, void 0, function* () {
            return false;
        });
    }
    setShouldAutopromptNow(value) {
        return cli_biometrics_service_awaiter(this, void 0, void 0, function* () { });
    }
    canEnableBiometricUnlock() {
        return cli_biometrics_service_awaiter(this, void 0, void 0, function* () {
            return false;
        });
    }
    setBiometricProtectedUnlockKeyForUser(userId, value) {
        return cli_biometrics_service_awaiter(this, void 0, void 0, function* () { });
    }
}

;// ../../libs/common/src/key-management/abstractions/process-reload.service.ts
class ProcessReloadServiceAbstraction {
}

;// ./src/key-management/cli-process-reload.service.ts
var cli_process_reload_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

/**
 * CLI implementation of ProcessReloadServiceAbstraction.
 * This is NOOP since there is no effective way to process reload the CLI.
 */
class CliProcessReloadService extends ProcessReloadServiceAbstraction {
    startProcessReload() {
        return cli_process_reload_service_awaiter(this, void 0, void 0, function* () { });
    }
    cancelProcessReload() {
        return cli_process_reload_service_awaiter(this, void 0, void 0, function* () { });
    }
}

;// ./src/key-management/session-timeout/services/cli-session-timeout-type.service.ts
var cli_session_timeout_type_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

class CliSessionTimeoutTypeService {
    isAvailable(timeout) {
        return cli_session_timeout_type_service_awaiter(this, void 0, void 0, function* () {
            return timeout === VaultTimeoutStringType.Never;
        });
    }
    getOrPromoteToAvailable(_) {
        return cli_session_timeout_type_service_awaiter(this, void 0, void 0, function* () {
            return VaultTimeoutStringType.Never;
        });
    }
}

;// ./src/platform/flags.ts

function flags_flagEnabled(flag) {
    return flagEnabled(flag);
}
function flags_devFlagEnabled(flag) {
    return baseDevFlagEnabled(flag);
}
function flags_devFlagValue(flag) {
    return baseDevFlagValue(flag);
}

;// external "child_process"
const external_child_process_namespaceObject = require("child_process");
;// external "open"
const external_open_namespaceObject = require("open");
var external_open_default = /*#__PURE__*/__webpack_require__.n(external_open_namespaceObject);
;// ./src/platform/services/cli-platform-utils.service.ts
var cli_platform_utils_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore



class CliPlatformUtilsService {
    constructor(clientType, packageJson) {
        this.packageJson = packageJson;
        this.deviceCache = null;
        this.clientType = clientType;
    }
    getDevice() {
        if (!this.deviceCache) {
            switch (process.platform) {
                case "win32":
                    this.deviceCache = DeviceType.WindowsCLI;
                    break;
                case "darwin":
                    this.deviceCache = DeviceType.MacOsCLI;
                    break;
                case "linux":
                default:
                    this.deviceCache = DeviceType.LinuxCLI;
                    break;
            }
        }
        return this.deviceCache;
    }
    getDeviceString() {
        const device = DeviceType[this.getDevice()].toLowerCase();
        return device.replace("cli", "");
    }
    getClientType() {
        return this.clientType;
    }
    isFirefox() {
        return false;
    }
    isChrome() {
        return false;
    }
    isEdge() {
        return false;
    }
    isOpera() {
        return false;
    }
    isVivaldi() {
        return false;
    }
    isSafari() {
        return false;
    }
    isChromium() {
        return false;
    }
    isMacAppStore() {
        return false;
    }
    isPopupOpen() {
        return Promise.resolve(false);
    }
    isAnyViewFocused() {
        return Promise.resolve(false);
    }
    launchUri(uri, options) {
        if (process.platform === "linux") {
            external_child_process_namespaceObject.spawnSync("xdg-open", [uri]);
        }
        else {
            // eslint-disable-next-line no-console
            external_open_default()(uri).catch(console.error);
        }
    }
    getApplicationVersion() {
        return Promise.resolve(this.packageJson.version);
    }
    getApplicationVersionNumber() {
        return cli_platform_utils_service_awaiter(this, void 0, void 0, function* () {
            return (yield this.getApplicationVersion()).split(RegExp("[+|-]"))[0].trim();
        });
    }
    getApplicationVersionSync() {
        return this.packageJson.version;
    }
    supportsWebAuthn(win) {
        return false;
    }
    supportsDuo() {
        return false;
    }
    supportsAutofill() {
        return false;
    }
    supportsFileDownloads() {
        return false;
    }
    showToast(type, title, text, options) {
        throw new Error("Not implemented.");
    }
    isDev() {
        return "production" === "development";
    }
    isSelfHost() {
        return false;
    }
    copyToClipboard(text, options) {
        throw new Error("Not implemented.");
    }
    readFromClipboard(options) {
        throw new Error("Not implemented.");
    }
    supportsSecureStorage() {
        return false;
    }
    getAutofillKeyboardShortcut() {
        return null;
    }
    packageType() {
        return cli_platform_utils_service_awaiter(this, void 0, void 0, function* () {
            return null;
        });
    }
}

;// ../../node_modules/@bitwarden/commercial-sdk-internal/index.js


// In order to support a fallback strategy for web we need to conditionally load the wasm file
function init(wasm) {
  (0,bitwarden_wasm_internal_bg/* __wbg_set_wasm */.lIU)(wasm);
}



;// ./src/platform/services/cli-sdk-load.service.ts
var cli_sdk_load_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};


class CliSdkLoadService extends SdkLoadService {
    load() {
        return cli_sdk_load_service_awaiter(this, void 0, void 0, function* () {
            // CLI uses stdout for user interaction / automations so we cannot log info / debug here.
            SdkLoadService.logLevel = bitwarden_wasm_internal_bg/* LogLevel */.$bb.Error;
            const module = yield __webpack_require__.e(/* import() */ 113).then(__webpack_require__.bind(__webpack_require__, 113));
            init(module);
        });
    }
}

;// ../../libs/common/src/platform/abstractions/system.service.ts
class SystemService {
}

;// ./src/platform/services/cli-system.service.ts
var cli_system_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

/**
 * CLI implementation of SystemService.
 * The implementation is NOOP since these functions are meant for GUI clients.
 */
class CliSystemService extends SystemService {
    clearClipboard(clipboardValue, timeoutMs) {
        return cli_system_service_awaiter(this, void 0, void 0, function* () { });
    }
    clearPendingClipboard() {
        return cli_system_service_awaiter(this, void 0, void 0, function* () { });
    }
}

;// ./src/platform/services/console-log.service.ts

class ConsoleLogService extends console_log_service_ConsoleLogService {
    constructor(isDev, filter = null) {
        super(isDev, filter);
    }
    write(level, message, ...optionalParams) {
        if (this.filter != null && this.filter(level)) {
            return;
        }
        if (process.env.BW_RESPONSE === "true") {
            // eslint-disable-next-line
            console.error(message, ...optionalParams);
            return;
        }
        super.write(level, message, ...optionalParams);
    }
}

;// ../../libs/common/src/platform/services/translation.service.ts
var translation_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
class TranslationService {
    constructor(systemLanguage, localesDirectory, getLocalesJson) {
        this.systemLanguage = systemLanguage;
        this.localesDirectory = localesDirectory;
        this.getLocalesJson = getLocalesJson;
        // First locale is the default (English)
        this.supportedTranslationLocales = ["en"];
        this.defaultLocale = "en";
        this.localeNames = new Map([
            ["af", "Afrikaans"],
            ["ar", "العربية الفصحى"],
            ["az", "Azərbaycanca"],
            ["be", "Беларуская"],
            ["bg", "български"],
            ["bn", "বাংলা"],
            ["bs", "bosanski jezik"],
            ["ca", "català"],
            ["cs", "čeština"],
            ["cy", "Cymraeg, y Gymraeg"],
            ["da", "dansk"],
            ["de", "Deutsch"],
            ["el", "Ελληνικά"],
            ["en", "English"],
            ["en-GB", "English (British)"],
            ["en-IN", "English (India)"],
            ["eo", "Esperanto"],
            ["es", "español"],
            ["et", "eesti"],
            ["eu", "euskara"],
            ["fa", "فارسی"],
            ["fi", "suomi"],
            ["fil", "Wikang Filipino"],
            ["fr", "français"],
            ["gl", "galego"],
            ["he", "עברית"],
            ["hi", "हिन्दी"],
            ["hr", "hrvatski"],
            ["hu", "magyar"],
            ["id", "Bahasa Indonesia"],
            ["it", "italiano"],
            ["ja", "日本語"],
            ["ka", "ქართული"],
            ["km", "ខ្មែរ, ខេមរភាសា, ភាសាខ្មែរ"],
            ["kn", "ಕನ್ನಡ"],
            ["ko", "한국어"],
            ["lt", "lietuvių kalba"],
            ["lv", "Latvietis"],
            ["me", "црногорски"],
            ["ml", "മലയാളം"],
            ["mr", "मराठी"],
            ["my", "ဗမာစကား"],
            ["nb", "norsk (bokmål)"],
            ["ne", "नेपाली"],
            ["nl", "Nederlands"],
            ["nn", "Norsk Nynorsk"],
            ["or", "ଓଡ଼ିଆ"],
            ["pl", "polski"],
            ["pt-BR", "português do Brasil"],
            ["pt-PT", "português"],
            ["ro", "română"],
            ["ru", "русский"],
            ["si", "සිංහල"],
            ["sk", "slovenčina"],
            ["sl", "Slovenski jezik, Slovenščina"],
            ["sr", "Српски"],
            ["sv", "svenska"],
            ["ta", "தமிழ்"],
            ["te", "తెలుగు"],
            ["th", "ไทย"],
            ["tr", "Türkçe"],
            ["uk", "українська"],
            ["vi", "Tiếng Việt"],
            ["zh-CN", "中文（中国大陆）"],
            ["zh-TW", "中文（台灣）"],
        ]);
        this.defaultMessages = {};
        this.localeMessages = {};
        this.systemLanguage = systemLanguage.replace("_", "-");
    }
    init(locale) {
        return translation_service_awaiter(this, void 0, void 0, function* () {
            if (this.inited) {
                throw new Error("i18n already initialized.");
            }
            if (this.supportedTranslationLocales == null || this.supportedTranslationLocales.length === 0) {
                throw new Error("supportedTranslationLocales not set.");
            }
            this.inited = true;
            this.translationLocale = locale != null ? locale : this.systemLanguage;
            try {
                this.collator = new Intl.Collator(this.translationLocale, {
                    numeric: true,
                    sensitivity: "base",
                });
            }
            catch (_a) {
                this.collator = null;
            }
            if (this.supportedTranslationLocales.indexOf(this.translationLocale) === -1) {
                this.translationLocale = this.translationLocale.slice(0, 2);
                if (this.supportedTranslationLocales.indexOf(this.translationLocale) === -1) {
                    this.translationLocale = this.defaultLocale;
                }
            }
            if (this.localesDirectory != null) {
                yield this.loadMessages(this.translationLocale, this.localeMessages);
                if (this.translationLocale !== this.defaultLocale) {
                    yield this.loadMessages(this.defaultLocale, this.defaultMessages);
                }
            }
        });
    }
    t(id, p1, p2, p3) {
        return this.translate(id, p1, p2, p3);
    }
    translate(id, p1, p2, p3) {
        let result;
        // eslint-disable-next-line
        if (this.localeMessages.hasOwnProperty(id) && this.localeMessages[id]) {
            result = this.localeMessages[id];
            // eslint-disable-next-line
        }
        else if (this.defaultMessages.hasOwnProperty(id) && this.defaultMessages[id]) {
            result = this.defaultMessages[id];
        }
        else {
            result = "";
        }
        if (result !== "") {
            if (p1 != null) {
                result = result.split("__$1__").join(p1.toString());
            }
            if (p2 != null) {
                result = result.split("__$2__").join(p2.toString());
            }
            if (p3 != null) {
                result = result.split("__$3__").join(p3.toString());
            }
        }
        return result;
    }
    loadMessages(locale, messagesObj) {
        return translation_service_awaiter(this, void 0, void 0, function* () {
            const formattedLocale = locale.replace("-", "_");
            const locales = yield this.getLocalesJson(formattedLocale);
            for (const prop in locales) {
                // eslint-disable-next-line
                if (!locales.hasOwnProperty(prop)) {
                    continue;
                }
                messagesObj[prop] = locales[prop].message;
                if (locales[prop].placeholders) {
                    for (const placeProp in locales[prop].placeholders) {
                        if (!locales[prop].placeholders.hasOwnProperty(placeProp) || // eslint-disable-line
                            !locales[prop].placeholders[placeProp].content) {
                            continue;
                        }
                        const replaceToken = "\\$" + placeProp.toUpperCase() + "\\$";
                        let replaceContent = locales[prop].placeholders[placeProp].content;
                        if (replaceContent === "$1" || replaceContent === "$2" || replaceContent === "$3") {
                            replaceContent = "__$" + replaceContent + "__";
                        }
                        messagesObj[prop] = messagesObj[prop].replace(new RegExp(replaceToken, "g"), replaceContent);
                    }
                }
            }
        });
    }
}

;// ../../libs/common/src/platform/services/i18n.service.ts
var i18n_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore



const i18n_service_LOCALE_KEY = new KeyDefinition(TRANSLATION_DISK, "locale", {
    deserializer: (value) => value,
});
class i18n_service_I18nService extends TranslationService {
    constructor(systemLanguage, localesDirectory, getLocalesJson, globalStateProvider) {
        super(systemLanguage, localesDirectory, getLocalesJson);
        this.systemLanguage = systemLanguage;
        this.localesDirectory = localesDirectory;
        this.getLocalesJson = getLocalesJson;
        this.translationLocaleState = globalStateProvider.get(i18n_service_LOCALE_KEY);
        this.userSetLocale$ = this.translationLocaleState.state$;
        this.locale$ = this.userSetLocale$.pipe((0,external_rxjs_namespaceObject.map)((locale) => locale !== null && locale !== void 0 ? locale : this.translationLocale));
    }
    setLocale(locale) {
        return i18n_service_awaiter(this, void 0, void 0, function* () {
            yield this.translationLocaleState.update(() => locale);
        });
    }
    init() {
        const _super = Object.create(null, {
            init: { get: () => super.init }
        });
        return i18n_service_awaiter(this, void 0, void 0, function* () {
            const storedLocale = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.translationLocaleState.state$);
            yield _super.init.call(this, storedLocale);
        });
    }
}

;// ./src/platform/services/i18n.service.ts



class I18nService extends i18n_service_I18nService {
    constructor(systemLanguage, localesDirectory, globalStateProvider) {
        super(systemLanguage, localesDirectory, (formattedLocale) => {
            const filePath = external_path_namespaceObject.join(__dirname, this.localesDirectory + "/" + formattedLocale + "/messages.json");
            const localesJson = external_fs_namespaceObject.readFileSync(filePath, "utf8");
            const locales = JSON.parse(localesJson.replace(/^\uFEFF/, "")); // strip the BOM
            return Promise.resolve(locales);
        }, globalStateProvider);
        this.supportedTranslationLocales = ["en"];
    }
}

;// external "lowdb"
const external_lowdb_namespaceObject = require("lowdb");
;// external "lowdb/adapters/FileSync"
const FileSync_namespaceObject = require("lowdb/adapters/FileSync");
;// external "proper-lockfile"
const external_proper_lockfile_namespaceObject = require("proper-lockfile");
;// ./src/platform/services/lowdb-storage.service.ts
var lowdb_storage_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore








const retries = {
    retries: 50,
    minTimeout: 100,
    maxTimeout: 250,
    factor: 2,
};
class LowdbStorageService {
    constructor(logService, defaults, dir, allowCache = false, requireLock = false) {
        this.logService = logService;
        this.dir = dir;
        this.allowCache = allowCache;
        this.requireLock = requireLock;
        this.ready = false;
        this.updatesSubject = new external_rxjs_namespaceObject.Subject();
        this.defaults = defaults;
        this.updates$ = this.updatesSubject.asObservable();
    }
    init() {
        return lowdb_storage_service_awaiter(this, void 0, void 0, function* () {
            if (this.ready) {
                return;
            }
            this.logService.info("Initializing lowdb storage service.");
            let adapter;
            if (utils_Utils.isNode && this.dir != null) {
                if (!external_fs_namespaceObject.existsSync(this.dir)) {
                    this.logService.warning(`Could not find dir, "${this.dir}"; creating it instead.`);
                    NodeUtils.mkdirpSync(this.dir, "700");
                    this.logService.info(`Created dir "${this.dir}".`);
                }
                this.dataFilePath = external_path_namespaceObject.join(this.dir, "data.json");
                if (!external_fs_namespaceObject.existsSync(this.dataFilePath)) {
                    this.logService.warning(`Could not find data file, "${this.dataFilePath}"; creating it instead.`);
                    external_fs_namespaceObject.writeFileSync(this.dataFilePath, "", { mode: 0o600 });
                    external_fs_namespaceObject.chmodSync(this.dataFilePath, 0o600);
                    this.logService.info(`Created data file "${this.dataFilePath}" with chmod 600.`);
                }
                else {
                    this.logService.info(`db file "${this.dataFilePath} already exists"; using existing db`);
                }
                yield this.lockDbFile(() => {
                    adapter = new FileSync_namespaceObject(this.dataFilePath);
                });
            }
            try {
                this.logService.info("Attempting to create lowdb storage adapter.");
                this.db = external_lowdb_namespaceObject(adapter);
                this.logService.info("Successfully created lowdb storage adapter.");
            }
            catch (e) {
                if (e instanceof SyntaxError) {
                    this.logService.warning(`Error creating lowdb storage adapter, "${e.message}"; emptying data file.`);
                    if (external_fs_namespaceObject.existsSync(this.dataFilePath)) {
                        const backupPath = this.dataFilePath + ".bak";
                        this.logService.warning(`Writing backup of data file to ${backupPath}`);
                        yield external_fs_namespaceObject.copyFile(this.dataFilePath, backupPath, () => {
                            this.logService.warning(`Error while creating data file backup, "${e.message}". No backup may have been created.`);
                        });
                    }
                    adapter.write({});
                    this.db = external_lowdb_namespaceObject(adapter);
                }
                else {
                    this.logService.error(`Error creating lowdb storage adapter, "${e.message}".`);
                    throw e;
                }
            }
            if (this.defaults != null) {
                // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
                // eslint-disable-next-line @typescript-eslint/no-floating-promises
                this.lockDbFile(() => {
                    this.logService.info("Writing defaults.");
                    this.readForNoCache();
                    this.db.defaults(this.defaults).write();
                    this.logService.info("Successfully wrote defaults to db.");
                });
            }
            this.ready = true;
        });
    }
    get valuesRequireDeserialization() {
        return true;
    }
    get(key) {
        return lowdb_storage_service_awaiter(this, void 0, void 0, function* () {
            yield this.waitForReady();
            return this.lockDbFile(() => {
                this.readForNoCache();
                const val = this.db.get(key).value();
                this.logService.debug(`Successfully read ${key} from db`);
                if (val == null) {
                    return null;
                }
                return val;
            });
        });
    }
    has(key) {
        return this.get(key).then((v) => v != null);
    }
    save(key, obj) {
        return lowdb_storage_service_awaiter(this, void 0, void 0, function* () {
            yield this.waitForReady();
            return this.lockDbFile(() => {
                this.readForNoCache();
                // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
                // eslint-disable-next-line @typescript-eslint/no-floating-promises
                this.db.set(key, obj).write();
                this.updatesSubject.next({ key, updateType: "save" });
                this.logService.debug(`Successfully wrote ${key} to db`);
                return;
            });
        });
    }
    remove(key) {
        return lowdb_storage_service_awaiter(this, void 0, void 0, function* () {
            yield this.waitForReady();
            return this.lockDbFile(() => {
                this.readForNoCache();
                // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
                // eslint-disable-next-line @typescript-eslint/no-floating-promises
                this.db.unset(key).write();
                this.updatesSubject.next({ key, updateType: "remove" });
                this.logService.debug(`Successfully removed ${key} from db`);
                return;
            });
        });
    }
    lockDbFile(action) {
        return lowdb_storage_service_awaiter(this, void 0, void 0, function* () {
            if (this.requireLock && !utils_Utils.isNullOrWhitespace(this.dataFilePath)) {
                this.logService.info("acquiring db file lock");
                return yield external_proper_lockfile_namespaceObject.lock(this.dataFilePath, { retries: retries }).then((release) => {
                    try {
                        return action();
                    }
                    finally {
                        // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
                        // eslint-disable-next-line @typescript-eslint/no-floating-promises
                        release();
                    }
                });
            }
            else {
                return action();
            }
        });
    }
    readForNoCache() {
        if (!this.allowCache) {
            this.db.read();
        }
    }
    waitForReady() {
        return lowdb_storage_service_awaiter(this, void 0, void 0, function* () {
            if (!this.ready) {
                yield this.init();
            }
        });
    }
}

;// external "form-data"
const external_form_data_namespaceObject = require("form-data");
;// external "https-proxy-agent"
const external_https_proxy_agent_namespaceObject = require("https-proxy-agent");
;// external "node-fetch"
const external_node_fetch_namespaceObject = require("node-fetch");
var external_node_fetch_default = /*#__PURE__*/__webpack_require__.n(external_node_fetch_namespaceObject);
;// ../../libs/common/src/admin-console/models/request/collection-bulk-delete.request.ts
class CollectionBulkDeleteRequest {
    constructor(ids) {
        this.ids = ids == null ? [] : ids;
    }
}

;// ../../libs/common/src/admin-console/models/response/organization-connection.response.ts

class OrganizationConnectionResponse extends BaseResponse {
    constructor(response, configType) {
        super(response);
        this.id = this.getResponseProperty("Id");
        this.type = this.getResponseProperty("Type");
        this.organizationId = this.getResponseProperty("OrganizationId");
        this.enabled = this.getResponseProperty("Enabled");
        const rawConfig = this.getResponseProperty("Config");
        this.config = rawConfig == null ? null : new configType(rawConfig);
    }
}

;// ../../libs/common/src/admin-console/models/response/organization-sponsorship-sync-status.response.ts

class OrganizationSponsorshipSyncStatusResponse extends BaseResponse {
    constructor(response) {
        super(response);
        const lastSyncDate = this.getResponseProperty("LastSyncDate");
        if (lastSyncDate) {
            this.lastSyncDate = new Date(lastSyncDate);
        }
    }
}

;// ../../libs/common/src/admin-console/models/response/pre-validate-sponsorship.response.ts

class PreValidateSponsorshipResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.isTokenValid = this.getResponseProperty("IsTokenValid");
        this.isFreeFamilyPolicyEnabled = this.getResponseProperty("IsFreeFamilyPolicyEnabled");
    }
}

;// ../../libs/common/src/admin-console/models/response/provider/provider-user-bulk-public-key.response.ts
// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop.
// eslint-disable-next-line no-restricted-imports

class ProviderUserBulkPublicKeyResponse extends OrganizationUserBulkPublicKeyResponse {
}

;// ../../libs/common/src/admin-console/models/response/provider/provider-user-bulk.response.ts

class ProviderUserBulkResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.id = this.getResponseProperty("Id");
        this.error = this.getResponseProperty("Error");
    }
}

;// ../../libs/common/src/admin-console/models/response/provider/provider-user.response.ts


class ProviderUserResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.id = this.getResponseProperty("Id");
        this.userId = this.getResponseProperty("UserId");
        this.type = this.getResponseProperty("Type");
        this.status = this.getResponseProperty("Status");
        this.permissions = new PermissionsApi(this.getResponseProperty("Permissions"));
    }
}
class ProviderUserUserDetailsResponse extends ProviderUserResponse {
    constructor(response) {
        super(response);
        this.name = this.getResponseProperty("Name");
        this.email = this.getResponseProperty("Email");
    }
}

;// ../../libs/common/src/auth/models/response/key-connector-user-key.response.ts

class KeyConnectorUserKeyResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.key = this.getResponseProperty("Key");
    }
}

;// ../../libs/common/src/auth/models/response/refresh-token.response.ts

class RefreshTokenResponse extends BaseResponse {
    constructor(response) {
        super(response);
        const accessToken = this.getResponseProperty("access_token");
        if (accessToken == null || typeof accessToken !== "string") {
            throw new Error("Refresh token response does not contain a valid access token");
        }
        const tokenType = this.getResponseProperty("token_type");
        if (tokenType == null || typeof tokenType !== "string") {
            throw new Error("Refresh token response does not contain a valid token type");
        }
        this.accessToken = accessToken;
        this.tokenType = tokenType;
        const expiresIn = this.getResponseProperty("expires_in");
        if (expiresIn != null && typeof expiresIn === "number") {
            this.expiresIn = expiresIn;
        }
        const refreshToken = this.getResponseProperty("refresh_token");
        if (refreshToken != null && typeof refreshToken === "string") {
            this.refreshToken = refreshToken;
        }
    }
}

;// ../../libs/common/src/auth/models/response/sso-pre-validate.response.ts

class SsoPreValidateResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.token = this.getResponseProperty("Token");
    }
}

;// ../../libs/common/src/models/response/global-domain.response.ts

class GlobalDomainResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.type = this.getResponseProperty("Type");
        this.domains = this.getResponseProperty("Domains");
        this.excluded = this.getResponseProperty("Excluded");
    }
}

;// ../../libs/common/src/models/response/domains.response.ts


class DomainsResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.globalEquivalentDomains = [];
        this.equivalentDomains = this.getResponseProperty("EquivalentDomains");
        const globalEquivalentDomains = this.getResponseProperty("GlobalEquivalentDomains");
        if (globalEquivalentDomains != null) {
            this.globalEquivalentDomains = globalEquivalentDomains.map((d) => new GlobalDomainResponse(d));
        }
        else {
            this.globalEquivalentDomains = [];
        }
    }
}

;// ../../libs/common/src/models/response/user-key.response.ts

class UserKeyResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.userId = this.getResponseProperty("UserId");
        this.publicKey = this.getResponseProperty("PublicKey");
    }
}

;// ../../libs/common/src/platform/misc/fetch-middleware.ts
/**
 * Composes an array of middlewares into a single {@link FetchFn} by chaining them
 * in order around a terminal fetch function. The first middleware in the array is
 * the outermost (called first, returns last), and each middleware's `next` parameter
 * invokes the next middleware in the chain, with the terminal as the innermost call.
 *
 * @param middlewares - Middlewares to compose, applied first-to-last (outermost-to-innermost).
 * @param terminal - The final fetch call invoked at the end of the chain (typically `nativeFetch`).
 * @returns A single {@link FetchFn} representing the full pipeline.
 */
function buildFetchPipeline(middlewares, terminal) {
    return middlewares.reduceRight((next, middleware) => (request) => middleware(request, next), terminal);
}

;// ../../libs/common/src/key-management/models/response/user-decryption.response.ts



class UserDecryptionResponse extends BaseResponse {
    constructor(response) {
        super(response);
        const masterPasswordUnlock = this.getResponseProperty("MasterPasswordUnlock");
        if (masterPasswordUnlock != null && typeof masterPasswordUnlock === "object") {
            this.masterPasswordUnlock = new MasterPasswordUnlockResponse(masterPasswordUnlock);
        }
        const webAuthnPrfOptions = this.getResponseProperty("WebAuthnPrfOptions");
        if (webAuthnPrfOptions != null && Array.isArray(webAuthnPrfOptions)) {
            this.webAuthnPrfOptions = webAuthnPrfOptions.map((option) => new WebAuthnPrfDecryptionOptionResponse(option));
        }
    }
}

;// ../../libs/common/src/platform/sync/sync.response.ts









class SyncResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.folders = [];
        this.collections = [];
        this.ciphers = [];
        this.policies = [];
        this.sends = [];
        const profile = this.getResponseProperty("Profile");
        if (profile != null) {
            this.profile = new ProfileResponse(profile);
        }
        const folders = this.getResponseProperty("Folders");
        if (folders != null) {
            this.folders = folders.map((f) => new folder_response_FolderResponse(f));
        }
        const collections = this.getResponseProperty("Collections");
        if (collections != null) {
            this.collections = collections.map((c) => new CollectionDetailsResponse(c));
        }
        const ciphers = this.getResponseProperty("Ciphers");
        if (ciphers != null) {
            this.ciphers = ciphers.map((c) => new cipher_response_CipherResponse(c));
        }
        const domains = this.getResponseProperty("Domains");
        if (domains != null) {
            this.domains = new DomainsResponse(domains);
        }
        const policies = this.getResponseProperty("Policies");
        if (policies != null) {
            this.policies = policies.map((p) => new PolicyResponse(p));
        }
        const sends = this.getResponseProperty("Sends");
        if (sends != null) {
            this.sends = sends.map((s) => new send_response_SendResponse(s));
        }
        const userDecryption = this.getResponseProperty("UserDecryption");
        if (userDecryption != null && typeof userDecryption === "object") {
            this.userDecryption = new UserDecryptionResponse(userDecryption);
        }
    }
}

;// ../../libs/common/src/platform/sync/index.ts



;// ../../libs/common/src/vault/models/response/attachment-upload-data.response.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


class AttachmentUploadDataResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.url = null;
        this.attachmentId = this.getResponseProperty("AttachmentId");
        this.fileUploadType = this.getResponseProperty("FileUploadType");
        const cipherResponse = this.getResponseProperty("CipherResponse");
        const cipherMiniResponse = this.getResponseProperty("CipherMiniResponse");
        this.cipherResponse = cipherResponse == null ? null : new cipher_response_CipherResponse(cipherResponse);
        this.cipherMiniResponse =
            cipherMiniResponse == null ? null : new cipher_response_CipherResponse(cipherMiniResponse);
        this.url = this.getResponseProperty("Url");
    }
}

;// ../../libs/common/src/vault/models/response/delete-attachment.response.ts


class DeleteAttachmentResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.cipher = new cipher_response_CipherResponse(this.getResponseProperty("Cipher"));
    }
}

;// ../../libs/common/src/vault/models/response/optional-cipher.response.ts


class OptionalCipherResponse extends BaseResponse {
    constructor(response) {
        super(response);
        this.unavailable = this.getResponseProperty("Unavailable");
        this.cipher = new cipher_response_CipherResponse(this.getResponseProperty("Cipher"));
    }
}

;// ../../libs/common/src/services/api-errors.ts
class InsecureUrlNotAllowedError extends Error {
    constructor(url) {
        if (url === undefined) {
            super("Insecure URL not allowed. All URLs must use HTTPS.");
        }
        else {
            super(`Insecure URL not allowed: ${url}. All URLs must use HTTPS.`);
        }
    }
}

;// ../../libs/common/src/services/api.service.ts
var api_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore












































/**
 * @deprecated The `ApiService` class is deprecated and calls should be extracted into individual
 * api services. The `send` method is still allowed to be used within api services. For background
 * of this decision please read https://contributing.bitwarden.com/architecture/adr/refactor-api-service.
 */
class ApiService {
    constructor(tokenService, platformUtilsService, environmentService, appIdService, refreshAccessTokenErrorCallback, logService, logoutCallback, vaultTimeoutSettingsService, accountService, httpOperations, customUserAgent = null) {
        this.tokenService = tokenService;
        this.platformUtilsService = platformUtilsService;
        this.environmentService = environmentService;
        this.appIdService = appIdService;
        this.refreshAccessTokenErrorCallback = refreshAccessTokenErrorCallback;
        this.logService = logService;
        this.logoutCallback = logoutCallback;
        this.vaultTimeoutSettingsService = vaultTimeoutSettingsService;
        this.accountService = accountService;
        this.httpOperations = httpOperations;
        this.customUserAgent = customUserAgent;
        this.refreshTokenPromise = {};
        /**
         * Middlewares wrap the fetch call in a chain. Each middleware receives the request and a `next`
         * function, and can modify requests, inspect/modify responses, retry, or short-circuit.
         */
        this.middlewares = [];
        this.device = platformUtilsService.getDevice();
        this.deviceType = this.device.toString();
    }
    // Auth APIs
    postIdentityToken(request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            var _a;
            const headers = new Headers({
                "Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
                Accept: "application/json",
                "Device-Type": this.deviceType,
            });
            if (this.customUserAgent != null) {
                headers.set("User-Agent", this.customUserAgent);
            }
            const identityToken = request instanceof UserApiTokenRequest
                ? request.toIdentityToken()
                : request.toIdentityToken(this.platformUtilsService.getClientType());
            const env = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.environmentService.environment$);
            const response = yield this.fetch(this.httpOperations.createRequest(env.getIdentityUrl() + "/connect/token", {
                body: this.qsStringify(identityToken),
                credentials: yield this.getCredentials(env),
                cache: "no-store",
                headers: headers,
                method: "POST",
            }));
            let responseJson = null;
            if (this.isJsonResponse(response)) {
                responseJson = yield response.json();
            }
            if (responseJson != null) {
                if (response.status === 200) {
                    return new IdentityTokenResponse(responseJson);
                }
                else if (response.status === 400 &&
                    responseJson.TwoFactorProviders2 &&
                    Object.keys(responseJson.TwoFactorProviders2).length) {
                    return new IdentityTwoFactorResponse(responseJson);
                }
                else if (response.status === 400 &&
                    ((_a = responseJson === null || responseJson === void 0 ? void 0 : responseJson.ErrorModel) === null || _a === void 0 ? void 0 : _a.Message) === ApiService.NEW_DEVICE_VERIFICATION_REQUIRED_MESSAGE) {
                    return new IdentityDeviceVerificationResponse(responseJson);
                }
                else if (response.status === 400 && (responseJson === null || responseJson === void 0 ? void 0 : responseJson.SsoOrganizationIdentifier)) {
                    return new IdentitySsoRequiredResponse(responseJson);
                }
            }
            return Promise.reject(new ErrorResponse(responseJson, response.status, true));
        });
    }
    refreshIdentityToken() {
        return api_service_awaiter(this, arguments, void 0, function* (userId = null) {
            const normalizedUser = (userId !== null && userId !== void 0 ? userId : (userId = yield this.getActiveUser()));
            if (normalizedUser == null) {
                throw new Error("No user provided and no active user, cannot refresh the identity token.");
            }
            try {
                yield this.refreshToken(normalizedUser);
            }
            catch (e) {
                this.logService.error("Error refreshing access token: ", e);
                throw e;
            }
        });
    }
    // TODO: PM-3519: Create and move to AuthRequest Api service
    getAuthRequest(id) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const path = `/auth-requests/${id}`;
            const r = yield this.send("GET", path, null, true, true);
            return new AuthRequestResponse(r);
        });
    }
    putAuthRequest(id, request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const path = `/auth-requests/${id}`;
            const r = yield this.send("PUT", path, request, true, true);
            return new AuthRequestResponse(r);
        });
    }
    getAuthRequests() {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const path = `/auth-requests/`;
            const r = yield this.send("GET", path, null, true, true);
            return new ListResponse(r, AuthRequestResponse);
        });
    }
    getLastAuthRequest() {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const requests = yield this.getAuthRequests();
            const activeRequests = requests.data.filter((m) => !m.isAnswered && !m.isExpired);
            const lastRequest = activeRequests.sort((a, b) => a.creationDate.localeCompare(b.creationDate))[activeRequests.length - 1];
            return lastRequest;
        });
    }
    // Account APIs
    getProfile() {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", "/accounts/profile", null, true, true);
            return new ProfileResponse(r);
        });
    }
    getUserSubscription() {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", "/accounts/subscription", null, true, true);
            return new SubscriptionResponse(r);
        });
    }
    putProfile(request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("PUT", "/accounts/profile", request, true, true);
            return new ProfileResponse(r);
        });
    }
    putAvatar(request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("PUT", "/accounts/avatar", request, true, true);
            return new ProfileResponse(r);
        });
    }
    postSetKeyConnectorKey(request) {
        return this.send("POST", "/accounts/set-key-connector-key", request, true, false);
    }
    postSecurityStamp(request) {
        return this.send("POST", "/accounts/security-stamp", request, true, false);
    }
    getAccountRevisionDate() {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", "/accounts/revision-date", null, true, true);
            return r;
        });
    }
    postPasswordHint(request) {
        return this.send("POST", "/accounts/password-hint", request, false, false);
    }
    postPremium(data) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("POST", "/accounts/premium", data, true, true);
            return new PaymentResponse(r);
        });
    }
    // TODO: Remove with deletion of pm-29594-update-individual-subscription-page
    postReinstatePremium() {
        return this.send("POST", "/accounts/reinstate-premium", null, true, false);
    }
    postAccountStorage(request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("POST", "/accounts/storage", request, true, true);
            return new PaymentResponse(r);
        });
    }
    postAccountLicense(data) {
        return this.send("POST", "/accounts/license", data, true, false);
    }
    postAccountKeys(request) {
        return this.send("POST", "/accounts/keys", request, true, false);
    }
    postAccountVerifyEmail() {
        return this.send("POST", "/accounts/verify-email", null, true, false);
    }
    postAccountVerifyEmailToken(request) {
        return this.send("POST", "/accounts/verify-email-token", request, false, false);
    }
    postAccountRecoverDelete(request) {
        return this.send("POST", "/accounts/delete-recover", request, false, false);
    }
    postAccountRecoverDeleteToken(request) {
        return this.send("POST", "/accounts/delete-recover-token", request, false, false);
    }
    postAccountKdf(request) {
        return this.send("POST", "/accounts/kdf", request, true, false);
    }
    deleteSsoUser(organizationId) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            return this.send("DELETE", "/accounts/sso/" + organizationId, null, true, false);
        });
    }
    getSsoUserIdentifier() {
        return api_service_awaiter(this, void 0, void 0, function* () {
            return this.send("GET", "/accounts/sso/user-identifier", null, true, true);
        });
    }
    postUserApiKey(id, request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("POST", "/accounts/api-key", request, true, true);
            return new ApiKeyResponse(r);
        });
    }
    postUserRotateApiKey(id, request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("POST", "/accounts/rotate-api-key", request, true, true);
            return new ApiKeyResponse(r);
        });
    }
    postConvertToKeyConnector() {
        return this.send("POST", "/accounts/convert-to-key-connector", null, true, false);
    }
    // Account Billing APIs
    getUserBillingHistory() {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", "/accounts/billing/history", null, true, true);
            return new BillingHistoryResponse(r);
        });
    }
    // Cipher APIs
    getCipher(id) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", "/ciphers/" + id, null, true, true);
            return new cipher_response_CipherResponse(r);
        });
    }
    getFullCipherDetails(id) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", "/ciphers/" + id + "/details", null, true, true);
            return new cipher_response_CipherResponse(r);
        });
    }
    getCipherAdmin(id) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", "/ciphers/" + id + "/admin", null, true, true);
            return new cipher_response_CipherResponse(r);
        });
    }
    getCiphersOrganization(organizationId, includeMemberItems) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            let url = "/ciphers/organization-details?organizationId=" + organizationId;
            if (includeMemberItems) {
                url += `&includeMemberItems=${includeMemberItems}`;
            }
            const r = yield this.send("GET", url, null, true, true);
            return new ListResponse(r, cipher_response_CipherResponse);
        });
    }
    postCipher(request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("POST", "/ciphers", request, true, true);
            return new cipher_response_CipherResponse(r);
        });
    }
    postCipherCreate(request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("POST", "/ciphers/create", request, true, true);
            return new cipher_response_CipherResponse(r);
        });
    }
    postCipherAdmin(request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("POST", "/ciphers/admin", request, true, true);
            return new cipher_response_CipherResponse(r);
        });
    }
    putCipher(id, request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("PUT", "/ciphers/" + id, request, true, true);
            return new cipher_response_CipherResponse(r);
        });
    }
    putPartialCipher(id, request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("PUT", "/ciphers/" + id + "/partial", request, true, true);
            return new cipher_response_CipherResponse(r);
        });
    }
    putCipherAdmin(id, request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("PUT", "/ciphers/" + id + "/admin", request, true, true);
            return new cipher_response_CipherResponse(r);
        });
    }
    deleteCipher(id) {
        return this.send("DELETE", "/ciphers/" + id, null, true, false);
    }
    deleteCipherAdmin(id) {
        return this.send("DELETE", "/ciphers/" + id + "/admin", null, true, false);
    }
    deleteManyCiphers(request) {
        return this.send("DELETE", "/ciphers", request, true, false);
    }
    deleteManyCiphersAdmin(request) {
        return this.send("DELETE", "/ciphers/admin", request, true, false);
    }
    putMoveCiphers(request) {
        return this.send("PUT", "/ciphers/move", request, true, false);
    }
    putShareCipher(id, request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("PUT", "/ciphers/" + id + "/share", request, true, true);
            return new cipher_response_CipherResponse(r);
        });
    }
    putShareCiphers(request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("PUT", "/ciphers/share", request, true, true);
            return new ListResponse(r, cipher_response_CipherResponse);
        });
    }
    putCipherCollections(id, request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.send("PUT", "/ciphers/" + id + "/collections_v2", request, true, true);
            return new OptionalCipherResponse(response);
        });
    }
    putCipherCollectionsAdmin(id, request) {
        return this.send("PUT", "/ciphers/" + id + "/collections-admin", request, true, true);
    }
    postPurgeCiphers(request, organizationId = null) {
        let path = "/ciphers/purge";
        if (organizationId != null) {
            path += "?organizationId=" + organizationId;
        }
        return this.send("POST", path, request, true, false);
    }
    putDeleteCipher(id) {
        return this.send("PUT", "/ciphers/" + id + "/delete", null, true, false);
    }
    putDeleteCipherAdmin(id) {
        return this.send("PUT", "/ciphers/" + id + "/delete-admin", null, true, false);
    }
    putDeleteManyCiphers(request) {
        return this.send("PUT", "/ciphers/delete", request, true, false);
    }
    putDeleteManyCiphersAdmin(request) {
        return this.send("PUT", "/ciphers/delete-admin", request, true, false);
    }
    putRestoreCipher(id) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("PUT", "/ciphers/" + id + "/restore", null, true, true);
            return new cipher_response_CipherResponse(r);
        });
    }
    putRestoreCipherAdmin(id) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("PUT", "/ciphers/" + id + "/restore-admin", null, true, true);
            return new cipher_response_CipherResponse(r);
        });
    }
    putRestoreManyCiphers(request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("PUT", "/ciphers/restore", request, true, true);
            return new ListResponse(r, cipher_response_CipherResponse);
        });
    }
    putRestoreManyCiphersAdmin(request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("PUT", "/ciphers/restore-admin", request, true, true);
            return new ListResponse(r, cipher_response_CipherResponse);
        });
    }
    // Attachments APIs
    getAttachmentData(cipherId, attachmentId, emergencyAccessId) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const path = (emergencyAccessId != null ? "/emergency-access/" + emergencyAccessId + "/" : "/ciphers/") +
                cipherId +
                "/attachment/" +
                attachmentId;
            const r = yield this.send("GET", path, null, true, true);
            return new attachment_response_AttachmentResponse(r);
        });
    }
    getAttachmentDataAdmin(cipherId, attachmentId) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const path = "/ciphers/" + cipherId + "/attachment/" + attachmentId + "/admin";
            const r = yield this.send("GET", path, null, true, true);
            return new attachment_response_AttachmentResponse(r);
        });
    }
    postCipherAttachment(id, request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("POST", "/ciphers/" + id + "/attachment/v2", request, true, true);
            return new AttachmentUploadDataResponse(r);
        });
    }
    deleteCipherAttachment(id, attachmentId) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("DELETE", "/ciphers/" + id + "/attachment/" + attachmentId, null, true, true);
            return new DeleteAttachmentResponse(r);
        });
    }
    deleteCipherAttachmentAdmin(id, attachmentId) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("DELETE", "/ciphers/" + id + "/attachment/" + attachmentId + "/admin", null, true, true);
            return new DeleteAttachmentResponse(r);
        });
    }
    postShareCipherAttachment(id, attachmentId, data, organizationId) {
        return this.send("POST", "/ciphers/" + id + "/attachment/" + attachmentId + "/share?organizationId=" + organizationId, data, true, false);
    }
    renewAttachmentUploadUrl(id, attachmentId) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", "/ciphers/" + id + "/attachment/" + attachmentId + "/renew", null, true, true);
            return new AttachmentUploadDataResponse(r);
        });
    }
    postAttachmentFile(id, attachmentId, data, options) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            if (typeof XMLHttpRequest !== "undefined" && (options === null || options === void 0 ? void 0 : options.onProgress)) {
                const userId = yield this.getActiveUser();
                const environment = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.environmentService.getEnvironment$(userId));
                const apiUrl = environment.getApiUrl();
                const headers = yield this.buildRequestHeaders();
                const request = new Request(`${apiUrl}/ciphers/${id}/attachment/${attachmentId}`, {
                    method: "POST",
                    body: data,
                    headers,
                });
                return this.nativeXMLHttpRequest(request, options.onProgress);
            }
            return this.send("POST", "/ciphers/" + id + "/attachment/" + attachmentId, data, true, false);
        });
    }
    // Collections APIs
    getCollectionAccessDetails(organizationId, id) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", "/organizations/" + organizationId + "/collections/" + id + "/details", null, true, true);
            return new CollectionAccessDetailsResponse(r);
        });
    }
    getUserCollections() {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", "/collections", null, true, true);
            return new ListResponse(r, CollectionResponse);
        });
    }
    getCollections(organizationId) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", "/organizations/" + organizationId + "/collections", null, true, true);
            return new ListResponse(r, CollectionResponse);
        });
    }
    getManyCollectionsWithAccessDetails(organizationId) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", "/organizations/" + organizationId + "/collections/details", null, true, true);
            return new ListResponse(r, CollectionAccessDetailsResponse);
        });
    }
    getCollectionUsers(organizationId, id) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", "/organizations/" + organizationId + "/collections/" + id + "/users", null, true, true);
            return r.map((dr) => new SelectionReadOnlyResponse(dr));
        });
    }
    postCollection(organizationId, request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("POST", "/organizations/" + organizationId + "/collections", request, true, true);
            return new CollectionAccessDetailsResponse(r);
        });
    }
    putCollection(organizationId, id, request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("PUT", "/organizations/" + organizationId + "/collections/" + id, request, true, true);
            return new CollectionAccessDetailsResponse(r);
        });
    }
    deleteCollection(organizationId, id) {
        return this.send("DELETE", "/organizations/" + organizationId + "/collections/" + id, null, true, false);
    }
    deleteManyCollections(organizationId, collectionIds) {
        return this.send("DELETE", "/organizations/" + organizationId + "/collections", new CollectionBulkDeleteRequest(collectionIds), true, false);
    }
    // Groups APIs
    getGroupUsers(organizationId, id) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", "/organizations/" + organizationId + "/groups/" + id + "/users", null, true, true);
            return r;
        });
    }
    deleteGroupUser(organizationId, id, organizationUserId) {
        return this.send("DELETE", "/organizations/" + organizationId + "/groups/" + id + "/user/" + organizationUserId, null, true, false);
    }
    // Plan APIs
    getPlans() {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", "/plans", null, false, true);
            return new ListResponse(r, PlanResponse);
        });
    }
    // Settings APIs
    getSettingsDomains() {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", "/settings/domains", null, true, true);
            return new DomainsResponse(r);
        });
    }
    putSettingsDomains(request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("PUT", "/settings/domains", request, true, true);
            return new DomainsResponse(r);
        });
    }
    // Sync APIs
    getSync() {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const path = !this.platformUtilsService.supportsAutofill()
                ? "/sync?excludeDomains=true"
                : "/sync";
            const r = yield this.send("GET", path, null, true, true);
            return new SyncResponse(r);
        });
    }
    // Organization APIs
    getCloudCommunicationsEnabled() {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", "/organizations/connections/enabled", null, true, true);
            return r;
        });
    }
    getOrganizationConnection(id, type, configType) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", `/organizations/connections/${id}/${type}`, null, true, true);
            return new OrganizationConnectionResponse(r, configType);
        });
    }
    createOrganizationConnection(request, configType) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("POST", "/organizations/connections/", request, true, true);
            return new OrganizationConnectionResponse(r, configType);
        });
    }
    updateOrganizationConnection(request, configType, organizationConnectionId) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("PUT", "/organizations/connections/" + organizationConnectionId, request, true, true);
            return new OrganizationConnectionResponse(r, configType);
        });
    }
    deleteOrganizationConnection(id) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            return this.send("DELETE", "/organizations/connections/" + id, null, true, false);
        });
    }
    // Provider User APIs
    getProviderUsers(providerId) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", "/providers/" + providerId + "/users", null, true, true);
            return new ListResponse(r, ProviderUserUserDetailsResponse);
        });
    }
    getProviderUser(providerId, id) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", "/providers/" + providerId + "/users/" + id, null, true, true);
            return new ProviderUserResponse(r);
        });
    }
    postProviderUserInvite(providerId, request) {
        return this.send("POST", "/providers/" + providerId + "/users/invite", request, true, false);
    }
    postProviderUserReinvite(providerId, id) {
        return this.send("POST", "/providers/" + providerId + "/users/" + id + "/reinvite", null, true, false);
    }
    postManyProviderUserReinvite(providerId, request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("POST", "/providers/" + providerId + "/users/reinvite", request, true, true);
            return new ListResponse(r, ProviderUserBulkResponse);
        });
    }
    postProviderUserBulkConfirm(providerId, request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("POST", "/providers/" + providerId + "/users/confirm", request, true, true);
            return new ListResponse(r, ProviderUserBulkResponse);
        });
    }
    deleteManyProviderUsers(providerId, request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("DELETE", "/providers/" + providerId + "/users", request, true, true);
            return new ListResponse(r, ProviderUserBulkResponse);
        });
    }
    postProviderUserAccept(providerId, id, request) {
        return this.send("POST", "/providers/" + providerId + "/users/" + id + "/accept", request, true, false);
    }
    postProviderUserConfirm(providerId, id, request) {
        return this.send("POST", "/providers/" + providerId + "/users/" + id + "/confirm", request, true, false);
    }
    postProviderUsersPublicKey(providerId, request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("POST", "/providers/" + providerId + "/users/public-keys", request, true, true);
            return new ListResponse(r, ProviderUserBulkPublicKeyResponse);
        });
    }
    putProviderUser(providerId, id, request) {
        return this.send("PUT", "/providers/" + providerId + "/users/" + id, request, true, false);
    }
    deleteProviderUser(providerId, id) {
        return this.send("DELETE", "/providers/" + providerId + "/users/" + id, null, true, false);
    }
    // Provider Organization APIs
    getProviderClients(providerId) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", "/providers/" + providerId + "/organizations", null, true, true);
            return new ListResponse(r, ProviderOrganizationOrganizationDetailsResponse);
        });
    }
    postProviderAddOrganization(providerId, request) {
        return this.send("POST", "/providers/" + providerId + "/organizations/add", request, true, false);
    }
    postProviderCreateOrganization(providerId, request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("POST", "/providers/" + providerId + "/organizations", request, true, true);
            return new ProviderOrganizationResponse(r);
        });
    }
    deleteProviderOrganization(providerId, id) {
        return this.send("DELETE", "/providers/" + providerId + "/organizations/" + id, null, true, false);
    }
    // Event APIs
    getEvents(start, end, token) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", this.addEventParameters("/events", start, end, token), null, true, true);
            return new ListResponse(r, EventResponse);
        });
    }
    getEventsCipher(id, start, end, token) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", this.addEventParameters("/ciphers/" + id + "/events", start, end, token), null, true, true);
            return new ListResponse(r, EventResponse);
        });
    }
    getEventsSecret(orgId, id, start, end, token) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", this.addEventParameters("/organization/" + orgId + "/secrets/" + id + "/events", start, end, token), null, true, true);
            return new ListResponse(r, EventResponse);
        });
    }
    getEventsServiceAccount(orgId, id, start, end, token) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", this.addEventParameters("/organization/" + orgId + "/service-account/" + id + "/events", start, end, token), null, true, true);
            return new ListResponse(r, EventResponse);
        });
    }
    getEventsProject(orgId, id, start, end, token) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", this.addEventParameters("/organization/" + orgId + "/projects/" + id + "/events", start, end, token), null, true, true);
            return new ListResponse(r, EventResponse);
        });
    }
    getEventsOrganization(id, start, end, token) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", this.addEventParameters("/organizations/" + id + "/events", start, end, token), null, true, true);
            return new ListResponse(r, EventResponse);
        });
    }
    getEventsOrganizationUser(organizationId, id, start, end, token) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", this.addEventParameters("/organizations/" + organizationId + "/users/" + id + "/events", start, end, token), null, true, true);
            return new ListResponse(r, EventResponse);
        });
    }
    getEventsProvider(id, start, end, token) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", this.addEventParameters("/providers/" + id + "/events", start, end, token), null, true, true);
            return new ListResponse(r, EventResponse);
        });
    }
    getEventsProviderUser(providerId, id, start, end, token) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", this.addEventParameters("/providers/" + providerId + "/users/" + id + "/events", start, end, token), null, true, true);
            return new ListResponse(r, EventResponse);
        });
    }
    postEventsCollect(request, userId) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const authHeader = yield this.tokenService.getAccessToken(userId);
            const headers = new Headers({
                "Device-Type": this.deviceType,
                Authorization: "Bearer " + authHeader,
                "Content-Type": "application/json; charset=utf-8",
            });
            if (this.customUserAgent != null) {
                headers.set("User-Agent", this.customUserAgent);
            }
            const env = yield (0,external_rxjs_namespaceObject.firstValueFrom)(userId == null
                ? this.environmentService.environment$
                : this.environmentService.getEnvironment$(userId));
            const response = yield this.fetch(this.httpOperations.createRequest(env.getEventsUrl() + "/collect", {
                cache: "no-store",
                credentials: yield this.getCredentials(env),
                method: "POST",
                body: JSON.stringify(request),
                headers: headers,
            }));
            if (response.status !== 200) {
                return Promise.reject("Event post failed.");
            }
        });
    }
    // User APIs
    getUserPublicKey(id) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("GET", "/users/" + id + "/public-key", null, true, true);
            return new UserKeyResponse(r);
        });
    }
    // Misc
    postBitPayInvoice(request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("POST", "/bitpay-invoice", request, true, true);
            return r;
        });
    }
    postSetupPayment() {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const r = yield this.send("POST", "/setup-payment", null, true, true);
            return r;
        });
    }
    // Key Connector
    getMasterKeyFromKeyConnector(keyConnectorUrl) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const activeUser = yield this.getActiveUser();
            if (activeUser == null) {
                throw new Error("No active user, cannot get master key from key connector.");
            }
            const authHeader = yield this.getActiveBearerToken(activeUser);
            const response = yield this.fetch(this.httpOperations.createRequest(keyConnectorUrl + "/user-keys", {
                cache: "no-store",
                method: "GET",
                headers: new Headers({
                    Accept: "application/json",
                    Authorization: "Bearer " + authHeader,
                }),
            }));
            if (response.status !== HttpStatusCode.Ok) {
                const error = yield this.handleApiRequestError(response, true);
                return Promise.reject(error);
            }
            return new KeyConnectorUserKeyResponse(yield response.json());
        });
    }
    postUserKeyToKeyConnector(keyConnectorUrl, request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const activeUser = yield this.getActiveUser();
            if (activeUser == null) {
                throw new Error("No active user, cannot post key to key connector.");
            }
            const authHeader = yield this.getActiveBearerToken(activeUser);
            const response = yield this.fetch(this.httpOperations.createRequest(keyConnectorUrl + "/user-keys", {
                cache: "no-store",
                method: "POST",
                headers: new Headers({
                    Accept: "application/json",
                    Authorization: "Bearer " + authHeader,
                    "Content-Type": "application/json; charset=utf-8",
                }),
                body: JSON.stringify(request),
            }));
            if (response.status !== HttpStatusCode.Ok) {
                const error = yield this.handleApiRequestError(response, true);
                return Promise.reject(error);
            }
        });
    }
    getKeyConnectorAlive(keyConnectorUrl) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.fetch(this.httpOperations.createRequest(keyConnectorUrl + "/alive", {
                cache: "no-store",
                method: "GET",
                headers: new Headers({
                    Accept: "application/json",
                    "Content-Type": "application/json; charset=utf-8",
                }),
            }));
            if (response.status !== HttpStatusCode.Ok) {
                const error = yield this.handleApiRequestError(response, true);
                return Promise.reject(error);
            }
        });
    }
    getActiveBearerToken(userId) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            let accessToken = yield this.tokenService.getAccessToken(userId);
            if (yield this.tokenService.tokenNeedsRefresh(userId)) {
                accessToken = yield this.refreshToken(userId);
            }
            return accessToken;
        });
    }
    addMiddleware(middleware) {
        this.middlewares.push(middleware);
    }
    fetch(request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            if (!request.url.startsWith("https://") && !this.platformUtilsService.isDev()) {
                throw new InsecureUrlNotAllowedError();
            }
            if (request.method === "GET") {
                request.headers.set("Cache-Control", "no-store");
                request.headers.set("Pragma", "no-cache");
            }
            yield this.applyPlatformHeaders(request.headers);
            const pipeline = buildFetchPipeline(this.middlewares, (req) => this.nativeFetch(req));
            return pipeline(request);
        });
    }
    nativeFetch(request) {
        return fetch(request);
    }
    nativeXMLHttpRequest(request, onProgress) {
        return new Promise((resolve, reject) => {
            const xhr = new XMLHttpRequest();
            xhr.open(request.method, request.url);
            request.headers.forEach((value, key) => xhr.setRequestHeader(key, value));
            xhr.responseType = "arraybuffer";
            xhr.upload.onprogress = (e) => {
                if (e.lengthComputable) {
                    onProgress(Math.round((e.loaded / e.total) * 100));
                }
            };
            xhr.onload = () => resolve(new Response(xhr.response, { status: xhr.status }));
            xhr.onerror = () => reject(new Error("Network error during upload"));
            void request
                .arrayBuffer()
                .then((body) => xhr.send(body))
                .catch(reject);
        });
    }
    applyPlatformHeaders(headers) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            headers.set("Bitwarden-Client-Name", this.platformUtilsService.getClientType());
            headers.set("Bitwarden-Client-Version", yield this.platformUtilsService.getApplicationVersionNumber());
            const packageType = yield this.platformUtilsService.packageType();
            if (packageType != null) {
                headers.set("Bitwarden-Package-Type", packageType);
            }
        });
    }
    buildRequestHeaders() {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const userId = yield this.getActiveUser();
            const accessToken = yield this.getActiveBearerToken(userId);
            const headers = new Headers({
                "Device-Type": this.deviceType,
                Authorization: "Bearer " + accessToken,
            });
            if (this.customUserAgent != null) {
                headers.set("User-Agent", this.customUserAgent);
            }
            if (flagEnabled("prereleaseBuild")) {
                headers.set("Is-Prerelease", "1");
            }
            yield this.applyPlatformHeaders(headers);
            return headers;
        });
    }
    preValidateSso(identifier) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            if (identifier == null || identifier === "") {
                throw new Error("Organization Identifier was not provided.");
            }
            const headers = new Headers({
                Accept: "application/json",
                "Device-Type": this.deviceType,
            });
            if (this.customUserAgent != null) {
                headers.set("User-Agent", this.customUserAgent);
            }
            const env = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.environmentService.environment$);
            const path = `/sso/prevalidate?domainHint=${encodeURIComponent(identifier)}`;
            const response = yield this.fetch(this.httpOperations.createRequest(env.getIdentityUrl() + path, {
                cache: "no-store",
                credentials: yield this.getCredentials(env),
                headers: headers,
                method: "GET",
            }));
            if (response.status === 200) {
                const body = yield response.json();
                return new SsoPreValidateResponse(body);
            }
            else {
                const error = yield this.handleApiRequestError(response, false);
                return Promise.reject(error);
            }
        });
    }
    postCreateSponsorship(sponsoredOrgId, request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            return yield this.send("POST", "/organization/sponsorship/" +
                (this.platformUtilsService.isSelfHost() ? "self-hosted/" : "") +
                sponsoredOrgId +
                "/families-for-enterprise", request, true, false);
        });
    }
    getSponsorshipSyncStatus(sponsoredOrgId) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.send("GET", "/organization/sponsorship/" + sponsoredOrgId + "/sync-status", null, true, true);
            return new OrganizationSponsorshipSyncStatusResponse(response);
        });
    }
    deleteRemoveSponsorship(sponsoringOrgId) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            return yield this.send("DELETE", "/organization/sponsorship/sponsored/" + sponsoringOrgId, null, true, false);
        });
    }
    postPreValidateSponsorshipToken(sponsorshipToken) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const response = yield this.send("POST", "/organization/sponsorship/validate-token?sponsorshipToken=" +
                encodeURIComponent(sponsorshipToken), null, true, true);
            return new PreValidateSponsorshipResponse(response);
        });
    }
    postRedeemSponsorship(sponsorshipToken, request) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            return yield this.send("POST", "/organization/sponsorship/redeem?sponsorshipToken=" + encodeURIComponent(sponsorshipToken), request, true, false);
        });
    }
    // Keep the running refreshTokenPromise to prevent parallel calls.
    refreshToken(userId) {
        if (this.refreshTokenPromise[userId] === undefined) {
            // TODO: Have different promise for each user
            this.refreshTokenPromise[userId] = this.internalRefreshToken(userId);
            void this.refreshTokenPromise[userId].finally(() => {
                delete this.refreshTokenPromise[userId];
            });
        }
        return this.refreshTokenPromise[userId];
    }
    internalRefreshToken(userId) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const refreshToken = yield this.tokenService.getRefreshToken(userId);
            if (refreshToken != null && refreshToken !== "") {
                return yield this.refreshAccessToken(userId);
            }
            const clientId = yield this.tokenService.getClientId(userId);
            const clientSecret = yield this.tokenService.getClientSecret(userId);
            if (!utils_Utils.isNullOrWhitespace(clientId) && !utils_Utils.isNullOrWhitespace(clientSecret)) {
                return yield this.refreshApiToken(userId);
            }
            this.refreshAccessTokenErrorCallback();
            throw new Error("Cannot refresh access token, no refresh token or api keys are stored.");
        });
    }
    refreshAccessToken(userId) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const refreshToken = yield this.tokenService.getRefreshToken(userId);
            if (refreshToken == null || refreshToken === "") {
                throw new Error();
            }
            const headers = new Headers({
                "Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
                Accept: "application/json",
                "Device-Type": this.deviceType,
            });
            if (this.customUserAgent != null) {
                headers.set("User-Agent", this.customUserAgent);
            }
            const env = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.environmentService.getEnvironment$(userId));
            const decodedToken = yield this.tokenService.decodeAccessToken(userId);
            const response = yield this.fetch(this.httpOperations.createRequest(env.getIdentityUrl() + "/connect/token", {
                body: this.qsStringify({
                    grant_type: "refresh_token",
                    client_id: decodedToken.client_id,
                    refresh_token: refreshToken,
                }),
                cache: "no-store",
                credentials: yield this.getCredentials(env),
                headers: headers,
                method: "POST",
            }));
            if (response.status === 200) {
                const responseJson = yield response.json();
                const tokenResponse = new RefreshTokenResponse(responseJson);
                const newDecodedAccessToken = yield this.tokenService.decodeAccessToken(tokenResponse.accessToken);
                const userId = newDecodedAccessToken.sub;
                const vaultTimeoutAction = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.vaultTimeoutSettingsService.getVaultTimeoutActionByUserId$(userId));
                const vaultTimeout = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.vaultTimeoutSettingsService.getVaultTimeoutByUserId$(userId));
                const refreshedTokens = yield this.tokenService.setTokens(tokenResponse.accessToken, vaultTimeoutAction, vaultTimeout, tokenResponse.refreshToken);
                return refreshedTokens.accessToken;
            }
            else {
                const error = yield this.handleTokenRefreshRequestError(response);
                return Promise.reject(error);
            }
        });
    }
    refreshApiToken(userId) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const clientId = yield this.tokenService.getClientId(userId);
            const clientSecret = yield this.tokenService.getClientSecret(userId);
            const appId = yield this.appIdService.getAppId();
            const deviceRequest = new DeviceRequest(appId, this.platformUtilsService);
            const tokenRequest = new UserApiTokenRequest(clientId, clientSecret, new TokenTwoFactorRequest(), deviceRequest);
            const response = yield this.postIdentityToken(tokenRequest);
            if (!(response instanceof IdentityTokenResponse)) {
                throw new Error("Invalid response received when refreshing api token");
            }
            const newDecodedAccessToken = yield this.tokenService.decodeAccessToken(response.accessToken);
            if (newDecodedAccessToken.sub !== userId) {
                throw new Error(`Token was supposed to be refreshed for ${userId} but the token we got back was for ${newDecodedAccessToken.sub}`);
            }
            const vaultTimeoutAction = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.vaultTimeoutSettingsService.getVaultTimeoutActionByUserId$(userId));
            const vaultTimeout = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.vaultTimeoutSettingsService.getVaultTimeoutByUserId$(userId));
            const refreshedToken = yield this.tokenService.setAccessToken(response.accessToken, vaultTimeoutAction, vaultTimeout);
            return refreshedToken;
        });
    }
    send(method, path, body, authedOrUserId, hasResponse, apiUrl, alterHeaders) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            var _a;
            // We assume that if there is a UserId making the request, it is also an authenticated
            // request and we will attempt to add an access token to the request.
            const userIdMakingRequest = yield this.getUserIdMakingRequest(authedOrUserId);
            const environment = yield (0,external_rxjs_namespaceObject.firstValueFrom)(userIdMakingRequest == null
                ? this.environmentService.environment$
                : this.environmentService.getEnvironment$(userIdMakingRequest));
            apiUrl = utils_Utils.isNullOrWhitespace(apiUrl) ? environment.getApiUrl() : apiUrl;
            const requestUrl = yield this.buildSafeApiRequestUrl(apiUrl, path);
            let request = yield this.buildRequest(method, userIdMakingRequest, environment, hasResponse, body, alterHeaders);
            let response = yield this.fetch(this.httpOperations.createRequest(requestUrl, request));
            // First, check to see if we were making an authenticated request and received an Unauthorized (401)
            // response.  This could mean that we attempted to make a request with an expired access token.
            // If so, attempt to refresh the token and try again.
            if (hasResponse &&
                userIdMakingRequest != null &&
                response.status === HttpStatusCode.Unauthorized) {
                this.logService.warning("Unauthorized response received for request to " + path + ". Attempting request again.");
                request = yield this.buildRequest(method, userIdMakingRequest, environment, hasResponse, body, alterHeaders);
                response = yield this.fetch(this.httpOperations.createRequest(requestUrl, request));
            }
            // At this point we are processing either the initial response or the response for the retry with the refreshed
            // access token.
            const responseType = response.headers.get("content-type");
            const responseIsJson = responseType != null && responseType.indexOf("application/json") !== -1;
            const responseIsCsv = responseType != null && responseType.indexOf("text/csv") !== -1;
            const responseIsBlob = responseType != null && responseType.indexOf("application/octet-stream") !== -1;
            if (hasResponse && response.status === HttpStatusCode.Ok && responseIsJson) {
                const responseJson = yield response.json();
                return responseJson;
            }
            else if (hasResponse && response.status === HttpStatusCode.Ok && responseIsCsv) {
                return yield response.text();
            }
            else if (hasResponse && response.status === HttpStatusCode.Ok && responseIsBlob) {
                const disposition = (_a = response.headers.get("Content-Disposition")) !== null && _a !== void 0 ? _a : "";
                const match = disposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
                const fileName = match ? match[1].replace(/['"]/g, "") : "download";
                const blob = yield response.blob();
                return { blob, fileName };
            }
            else if (response.status !== HttpStatusCode.Ok &&
                response.status !== HttpStatusCode.NoContent) {
                const error = yield this.handleApiRequestError(response, userIdMakingRequest != null);
                return Promise.reject(error);
            }
        });
    }
    buildSafeApiRequestUrl(apiUrl, path) {
        const pathParts = path.split("?");
        // Supplementary heuristic: detect common traversal indicators before normalization.
        const fullUrlPath = apiUrl + pathParts[0] + (pathParts.length > 1 ? `?${pathParts[1]}` : "");
        if (utils_Utils.containsTraversalIndicators(fullUrlPath)) {
            throw new Error("The request URL contains unexpected patterns.");
        }
        const requestUrl = apiUrl + utils_Utils.normalizePath(pathParts[0]) + (pathParts.length > 1 ? `?${pathParts[1]}` : "");
        return requestUrl;
    }
    getUserIdMakingRequest(authedOrUserId) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            if (authedOrUserId == null) {
                throw new Error("A user id was given but it was null, cannot complete API request.");
            }
            let userId = null;
            if (typeof authedOrUserId === "boolean" && authedOrUserId) {
                // Backwards compatible for authenticating the active user when `true` is passed in
                userId = yield this.getActiveUser();
            }
            else if (typeof authedOrUserId === "string") {
                userId = authedOrUserId;
            }
            return userId;
        });
    }
    buildRequest(method, userForAccessToken, environment, hasResponse, body, alterHeaders) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const [requestHeaders, requestBody] = yield this.buildHeadersAndBody(userForAccessToken, hasResponse, body, alterHeaders);
            const requestInit = {
                cache: "no-store",
                credentials: yield this.getCredentials(environment),
                method: method,
            };
            requestInit.headers = requestHeaders;
            requestInit.body = requestBody;
            return requestInit;
        });
    }
    buildHeadersAndBody(userForAccessToken, hasResponse, body, alterHeaders) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            let requestBody = null;
            const headers = new Headers({
                "Device-Type": this.deviceType,
            });
            if (flagEnabled("prereleaseBuild")) {
                headers.set("Is-Prerelease", "1");
            }
            if (this.customUserAgent != null) {
                headers.set("User-Agent", this.customUserAgent);
            }
            if (hasResponse) {
                headers.set("Accept", "application/json");
            }
            if (alterHeaders != null) {
                alterHeaders(headers);
            }
            if (userForAccessToken != null) {
                const authHeader = yield this.getActiveBearerToken(userForAccessToken);
                headers.set("Authorization", "Bearer " + authHeader);
            }
            else {
                // For unauthenticated requests, we need to tell the server what the device is for flag targeting,
                // since it won't be able to get it from the access token.
                const appId = yield this.appIdService.getAppId();
                headers.set("Device-Identifier", appId);
            }
            if (body != null) {
                if (typeof body === "string") {
                    requestBody = body;
                    headers.set("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
                }
                else if (typeof body === "object") {
                    if (body instanceof FormData) {
                        requestBody = body;
                    }
                    else {
                        headers.set("Content-Type", "application/json; charset=utf-8");
                        requestBody = JSON.stringify(body);
                    }
                }
            }
            return [headers, requestBody];
        });
    }
    /**
     * Handle an error response from a request to the Bitwarden API.
     * If the request is made with an access token (aka the user is authenticated),
     * and we receive a 401 or 403 response, we will log the user out, as this indicates
     * that the access token used on the request is either expired or does not have the appropriate permissions.
     * It is unlikely that it is expired, as we attempt to refresh the token on initial failure.
     * @param response The response from the API request
     * @param userIsAuthenticated A boolean indicating whether this is an authenticated request.
     * @returns An ErrorResponse with a message based on the response status.
     */
    handleApiRequestError(response, userIsAuthenticated) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            if (userIsAuthenticated &&
                (response.status === HttpStatusCode.Unauthorized ||
                    response.status === HttpStatusCode.Forbidden)) {
                yield this.logoutCallback("invalidAccessToken");
            }
            const responseJson = yield this.getJsonResponse(response);
            return new ErrorResponse(responseJson, response.status);
        });
    }
    /**
     * Handle an error response when trying to refresh an access token.
     * If the error indicates that the user's session has expired, it will log the user out.
     * @param response The response from the token refresh request.
     * @returns An ErrorResponse with a message based on the response status.
     */
    handleTokenRefreshRequestError(response) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            const responseJson = yield this.getJsonResponse(response);
            // IdentityServer will return an invalid_grant response if the refresh token has expired.
            // This means that the user's session has expired, and they need to log out.
            // We issue the logoutCallback() to log the user out through messaging.
            if (response.status === HttpStatusCode.BadRequest && (responseJson === null || responseJson === void 0 ? void 0 : responseJson.error) === "invalid_grant") {
                yield this.logoutCallback("sessionExpired");
            }
            return new ErrorResponse(responseJson, response.status, true);
        });
    }
    getJsonResponse(response) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            let responseJson = null;
            if (this.isJsonResponse(response)) {
                responseJson = yield response.json();
            }
            else if (this.isTextPlainResponse(response)) {
                responseJson = { Message: yield response.text() };
            }
            return responseJson;
        });
    }
    qsStringify(params) {
        return Object.keys(params)
            .map((key) => {
            return encodeURIComponent(key) + "=" + encodeURIComponent(params[key]);
        })
            .join("&");
    }
    getActiveUser() {
        return api_service_awaiter(this, void 0, void 0, function* () {
            return yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$.pipe((0,external_rxjs_namespaceObject.map)((a) => a === null || a === void 0 ? void 0 : a.id)));
        });
    }
    getCredentials(env) {
        return api_service_awaiter(this, void 0, void 0, function* () {
            if (this.platformUtilsService.getClientType() !== src_ClientType.Web || env.hasBaseUrl()) {
                return "include";
            }
            return undefined;
        });
    }
    addEventParameters(base, start, end, token) {
        if (start != null) {
            base += "?start=" + start;
        }
        if (end != null) {
            base += base.indexOf("?") > -1 ? "&" : "?";
            base += "end=" + end;
        }
        if (token != null) {
            base += base.indexOf("?") > -1 ? "&" : "?";
            base += "continuationToken=" + token;
        }
        return base;
    }
    isJsonResponse(response) {
        const typeHeader = response.headers.get("content-type");
        return typeHeader != null && typeHeader.indexOf("application/json") > -1;
    }
    isTextPlainResponse(response) {
        const typeHeader = response.headers.get("content-type");
        return typeHeader != null && typeHeader.indexOf("text/plain") > -1;
    }
}
/**
 * The message (responseJson.ErrorModel.Message) that comes back from the server when a new device verification is required.
 */
ApiService.NEW_DEVICE_VERIFICATION_REQUIRED_MESSAGE = "new device verification required";

;// ./src/platform/services/node-api.service.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore




global.fetch = (external_node_fetch_default());
global.Request = external_node_fetch_namespaceObject.Request;
global.Response = external_node_fetch_namespaceObject.Response;
global.Headers = external_node_fetch_namespaceObject.Headers;
global.FormData = external_form_data_namespaceObject;
class NodeApiService extends ApiService {
    constructor(tokenService, platformUtilsService, environmentService, appIdService, refreshAccessTokenErrorCallback, logService, logoutCallback, vaultTimeoutSettingsService, accountService, customUserAgent = null) {
        super(tokenService, platformUtilsService, environmentService, appIdService, refreshAccessTokenErrorCallback, logService, logoutCallback, vaultTimeoutSettingsService, accountService, { createRequest: (url, request) => new Request(url, request) }, customUserAgent);
    }
    nativeFetch(request) {
        const proxy = process.env.http_proxy || process.env.https_proxy;
        if (proxy) {
            request.agent = new external_https_proxy_agent_namespaceObject.HttpsProxyAgent(proxy);
        }
        return fetch(request);
    }
    /** XMLHttpRequest is not supported in Node.js, fallback to fetch */
    nativeXMLHttpRequest(request, _onProgress) {
        return this.nativeFetch(request);
    }
}

;// ./src/platform/services/node-env-secure-storage.service.ts
var node_env_secure_storage_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore




class NodeEnvSecureStorageService {
    constructor(storageService, logService, encryptService) {
        this.storageService = storageService;
        this.logService = logService;
        this.encryptService = encryptService;
    }
    get valuesRequireDeserialization() {
        return true;
    }
    get updates$() {
        return (0,external_rxjs_namespaceObject.throwError)(() => new Error("Secure storage implementations cannot have their updates subscribed to."));
    }
    get(key) {
        return node_env_secure_storage_service_awaiter(this, void 0, void 0, function* () {
            const value = yield this.storageService.get(this.makeProtectedStorageKey(key));
            if (value == null) {
                return null;
            }
            const obj = yield this.decrypt(value);
            return obj;
        });
    }
    has(key) {
        return node_env_secure_storage_service_awaiter(this, void 0, void 0, function* () {
            return (yield this.get(key)) != null;
        });
    }
    save(key, obj) {
        return node_env_secure_storage_service_awaiter(this, void 0, void 0, function* () {
            if (obj == null) {
                return this.remove(key);
            }
            if (obj !== null && typeof obj !== "string") {
                throw new Error("Only string storage is allowed.");
            }
            const protectedObj = yield this.encrypt(obj);
            yield this.storageService.save(this.makeProtectedStorageKey(key), protectedObj);
        });
    }
    remove(key) {
        return node_env_secure_storage_service_awaiter(this, void 0, void 0, function* () {
            yield this.storageService.remove(this.makeProtectedStorageKey(key));
            return;
        });
    }
    encrypt(plainValue) {
        return node_env_secure_storage_service_awaiter(this, void 0, void 0, function* () {
            const sessionKey = this.getSessionKey();
            if (sessionKey == null) {
                throw new Error("No session key available.");
            }
            const encValue = yield this.encryptService.encryptFileData(utils_Utils.fromB64ToArray(plainValue), sessionKey);
            if (encValue == null) {
                throw new Error("Value didn't encrypt.");
            }
            return utils_Utils.fromBufferToB64(encValue.buffer);
        });
    }
    decrypt(encValue) {
        return node_env_secure_storage_service_awaiter(this, void 0, void 0, function* () {
            try {
                const sessionKey = this.getSessionKey();
                if (sessionKey == null) {
                    return null;
                }
                const encBuf = EncArrayBuffer.fromB64(encValue);
                const decValue = yield this.encryptService.decryptFileData(encBuf, sessionKey);
                if (decValue == null) {
                    this.logService.info("Failed to decrypt.");
                    return null;
                }
                return utils_Utils.fromBufferToB64(decValue);
                // FIXME: Remove when updating file. Eslint update
                // eslint-disable-next-line @typescript-eslint/no-unused-vars
            }
            catch (e) {
                this.logService.info("Decrypt error.");
                return null;
            }
        });
    }
    getSessionKey() {
        try {
            if (process.env.BW_SESSION != null) {
                const sessionBuffer = utils_Utils.fromB64ToArray(process.env.BW_SESSION);
                if (sessionBuffer != null) {
                    const sessionKey = new SymmetricCryptoKey(sessionBuffer);
                    if (sessionBuffer != null) {
                        return sessionKey;
                    }
                }
            }
            // FIXME: Remove when updating file. Eslint update
            // eslint-disable-next-line @typescript-eslint/no-unused-vars
        }
        catch (e) {
            this.logService.info("Session key is invalid.");
        }
        return null;
    }
    makeProtectedStorageKey(key) {
        return "__PROTECTED__" + key;
    }
}

;// ./src/vault/services/cli-restricted-item-types.service.ts
var cli_restricted_item_types_service_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};

class CliRestrictedItemTypesService {
    constructor(restrictedItemTypesService) {
        this.restrictedItemTypesService = restrictedItemTypesService;
    }
    /**
     * Gets all restricted cipher types for the current user.
     *
     * @returns Promise resolving to array of restricted cipher types with allowed organization IDs
     */
    getRestrictedTypes() {
        return cli_restricted_item_types_service_awaiter(this, void 0, void 0, function* () {
            return (0,external_rxjs_namespaceObject.firstValueFrom)(this.restrictedItemTypesService.restricted$);
        });
    }
    /**
     * Filters out restricted cipher types from an array of ciphers.
     *
     * @param ciphers - Array of ciphers to filter
     * @returns Promise resolving to filtered array with restricted ciphers removed
     */
    filterRestrictedCiphers(ciphers) {
        return cli_restricted_item_types_service_awaiter(this, void 0, void 0, function* () {
            const restrictions = yield this.getRestrictedTypes();
            return ciphers.filter((cipher) => !this.restrictedItemTypesService.isCipherRestricted(cipher, restrictions));
        });
    }
    /**
     * Checks if a specific cipher type is restricted for the user.
     *
     * @param cipherType - The cipher type to check
     * @returns Promise resolving to true if the cipher type is restricted, false otherwise
     */
    isCipherRestricted(cipher) {
        return cli_restricted_item_types_service_awaiter(this, void 0, void 0, function* () {
            return (0,external_rxjs_namespaceObject.firstValueFrom)(this.restrictedItemTypesService.isCipherRestricted$(cipher));
        });
    }
}

;// ./src/service-container/service-container.ts
var service_container_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
































































// eslint-disable-next-line no-restricted-imports -- Needed for service construction









































// Polyfills
global.DOMParser = new external_jsdom_namespaceObject.JSDOM().window.DOMParser;
// eslint-disable-next-line
const packageJson = __webpack_require__(330);
/**
 * Instantiates services and makes them available for dependency injection.
 * Any Bitwarden-licensed services should be registered here.
 */
class service_container_ServiceContainer {
    constructor() {
        var _a, _b, _c;
        this.inited = false;
        let p = null;
        const relativeDataDir = external_path_namespaceObject.join(external_path_namespaceObject.dirname(process.execPath), "bw-data");
        if (external_fs_namespaceObject.existsSync(relativeDataDir)) {
            p = relativeDataDir;
        }
        else if (process.env.BITWARDENCLI_APPDATA_DIR) {
            p = external_path_namespaceObject.resolve(process.env.BITWARDENCLI_APPDATA_DIR);
        }
        else if (process.platform === "darwin") {
            p = external_path_namespaceObject.join((_a = process.env.HOME) !== null && _a !== void 0 ? _a : "", "Library/Application Support/Bitwarden CLI");
        }
        else if (process.platform === "win32") {
            p = external_path_namespaceObject.join((_b = process.env.APPDATA) !== null && _b !== void 0 ? _b : "", "Bitwarden CLI");
        }
        else if (process.env.XDG_CONFIG_HOME) {
            p = external_path_namespaceObject.join(process.env.XDG_CONFIG_HOME, "Bitwarden CLI");
        }
        else {
            p = external_path_namespaceObject.join((_c = process.env.HOME) !== null && _c !== void 0 ? _c : "", ".config/Bitwarden CLI");
        }
        const logoutCallback = () => service_container_awaiter(this, void 0, void 0, function* () { return yield this.logout(); });
        this.platformUtilsService = new CliPlatformUtilsService(src_ClientType.Cli, packageJson);
        this.logService = new ConsoleLogService(this.platformUtilsService.isDev(), (level) => process.env.BITWARDENCLI_DEBUG !== "true" && level <= LogLevel.Info);
        this.cryptoFunctionService = new NodeCryptoFunctionService();
        this.encryptService = new EncryptServiceImplementation(this.cryptoFunctionService, this.logService, true);
        this.storageService = new LowdbStorageService(this.logService, null, p, false, true);
        this.secureStorageService = new NodeEnvSecureStorageService(this.storageService, this.logService, 
        // MAC failures for secure storage are being logged for customers today and
        // they occur when users unlock / login and refresh a session key but don't
        // export it into their environment (e.g. BW_SESSION_KEY). This leaves a stale
        // BW_SESSION key in the env which is attempted to be used to decrypt the auto
        // unlock user key which obviously fails. So, to resolve this, we will not log
        // MAC failures for secure storage.
        new EncryptServiceImplementation(this.cryptoFunctionService, this.logService, false));
        this.memoryStorageService = new MemoryStorageService();
        this.memoryStorageForStateProviders = new SerializedMemoryStorageService();
        const storageServiceProvider = new StorageServiceProvider(this.storageService, this.memoryStorageForStateProviders);
        this.globalStateProvider = new DefaultGlobalStateProvider(storageServiceProvider, this.logService);
        const stateEventRegistrarService = new DefaultStateEventRegistrarService(this.globalStateProvider, storageServiceProvider);
        this.stateEventRunnerService = new DefaultStateEventRunnerService(this.globalStateProvider, storageServiceProvider);
        this.i18nService = new I18nService("en", "./locales", this.globalStateProvider);
        this.singleUserStateProvider = new DefaultSingleUserStateProvider(storageServiceProvider, stateEventRegistrarService, this.logService);
        this.messagingService = MessageSender.EMPTY;
        this.accountService = new AccountServiceImplementation(this.messagingService, this.logService, this.globalStateProvider, this.singleUserStateProvider);
        const activeUserAccessor = new DefaultActiveUserAccessor(this.accountService);
        this.activeUserStateProvider = new DefaultActiveUserStateProvider(activeUserAccessor, this.singleUserStateProvider);
        this.derivedStateProvider = new DefaultDerivedStateProvider();
        this.stateProvider = new DefaultStateProvider(this.activeUserStateProvider, this.singleUserStateProvider, this.globalStateProvider, this.derivedStateProvider);
        this.accountCryptographicStateService = new DefaultAccountCryptographicStateService(this.stateProvider);
        this.securityStateService = new DefaultSecurityStateService(this.accountCryptographicStateService);
        this.environmentService = new DefaultEnvironmentService(this.stateProvider, this.accountService, process.env.ADDITIONAL_REGIONS);
        this.keyGenerationService = new DefaultKeyGenerationService(this.cryptoFunctionService);
        this.tokenService = new TokenService(this.singleUserStateProvider, this.globalStateProvider, this.platformUtilsService.supportsSecureStorage(), this.secureStorageService, this.keyGenerationService, this.encryptService, this.logService, logoutCallback);
        this.migrationRunner = new MigrationRunner(this.storageService, this.logService, new MigrationBuilderService(), src_ClientType.Cli);
        this.stateService = new DefaultStateService(this.storageService, this.secureStorageService, activeUserAccessor);
        this.kdfConfigService = new DefaultKdfConfigService(this.stateProvider);
        this.masterPasswordService = new MasterPasswordService(this.stateProvider, this.keyGenerationService, this.logService, this.cryptoFunctionService, this.accountService);
        this.keyService = new DefaultKeyService(this.masterPasswordService, this.keyGenerationService, this.cryptoFunctionService, this.encryptService, this.platformUtilsService, this.logService, this.stateService, this.accountService, this.stateProvider, this.kdfConfigService, this.accountCryptographicStateService);
        const pinStateService = new PinStateService(this.stateProvider);
        this.pinService = new PinService(this.encryptService, this.logService, this.keyService, this.sdkService, pinStateService);
        this.masterPasswordUnlockService = new DefaultMasterPasswordUnlockService(this.masterPasswordService, this.keyService, this.logService);
        this.appIdService = new AppIdService(this.storageService, this.logService);
        const customUserAgent = "Bitwarden_CLI/" +
            this.platformUtilsService.getApplicationVersionSync() +
            " (" +
            this.platformUtilsService.getDeviceString().toUpperCase() +
            ")";
        this.biometricStateService = new DefaultBiometricStateService(this.stateProvider);
        this.userDecryptionOptionsService = new UserDecryptionOptionsService(this.singleUserStateProvider);
        this.ssoUrlService = new SsoUrlService();
        this.organizationService = new DefaultOrganizationService(this.stateProvider);
        this.policyService = new DefaultPolicyService(this.stateProvider, this.organizationService, this.accountService);
        const sessionTimeoutTypeService = new CliSessionTimeoutTypeService();
        this.vaultTimeoutSettingsService = new VaultTimeoutSettingsService(this.accountService, pinStateService, this.userDecryptionOptionsService, this.keyService, this.tokenService, this.policyService, this.biometricStateService, this.stateProvider, this.logService, VaultTimeoutStringType.Never, // default vault timeout
        sessionTimeoutTypeService);
        const refreshAccessTokenErrorCallback = () => {
            throw new Error("Refresh Access token error");
        };
        this.apiService = new NodeApiService(this.tokenService, this.platformUtilsService, this.environmentService, this.appIdService, refreshAccessTokenErrorCallback, this.logService, logoutCallback, this.vaultTimeoutSettingsService, this.accountService, customUserAgent);
        this.containerService = new ContainerService(this.keyService, this.encryptService);
        this.configApiService = new ConfigApiService(this.apiService);
        this.twoFactorApiService = new DefaultTwoFactorApiService(this.apiService);
        this.authService = new AuthService(this.accountService, this.messagingService, this.keyService, this.apiService, this.stateService, this.tokenService);
        this.configService = new DefaultConfigService(this.configApiService, this.environmentService, this.logService, this.stateProvider, this.authService);
        this.domainSettingsService = new DefaultDomainSettingsService(this.stateProvider, this.policyService, this.accountService, this.configService, this.environmentService, this.authService);
        this.fileUploadService = new FileUploadService(this.logService, this.apiService, this.configService);
        this.sendStateProvider = new SendStateProvider(this.stateProvider);
        this.sendService = new SendService(this.accountService, this.keyService, this.i18nService, this.keyGenerationService, this.sendStateProvider, this.encryptService, this.configService);
        this.cipherFileUploadService = new CipherFileUploadService(this.apiService, this.fileUploadService, this.configService);
        this.sendApiService = this.sendApiService = new SendApiService(this.apiService, this.fileUploadService, this.sendService);
        this.sendPasswordService = new DefaultSendPasswordService(this.cryptoFunctionService);
        this.searchService = new SearchService(this.logService, this.i18nService, this.stateProvider);
        this.collectionService = new DefaultCollectionService(this.keyService, this.encryptService, this.i18nService, this.stateProvider);
        this.providerService = new ProviderService(this.stateProvider);
        this.policyApiService = new PolicyApiService(this.policyService, this.apiService, this.accountService);
        const sdkClientFactory = flags_flagEnabled("sdk")
            ? new DefaultSdkClientFactory()
            : new NoopSdkClientFactory();
        this.sdkLoadService = new CliSdkLoadService();
        this.sdkService = new DefaultSdkService(sdkClientFactory, this.environmentService, this.platformUtilsService, this.accountService, this.kdfConfigService, this.keyService, this.accountCryptographicStateService, this.apiService, this.stateProvider, this.configService, customUserAgent);
        this.registerSdkService = new DefaultRegisterSdkService(sdkClientFactory, this.environmentService, this.platformUtilsService, this.accountService, this.apiService, this.stateProvider, this.configService, customUserAgent);
        this.unlockService = new DefaultUnlockService(this.registerSdkService, this.accountCryptographicStateService, pinStateService, this.kdfConfigService, this.accountService, this.masterPasswordService, this.stateProvider, this.logService, new CliBiometricsService(), this.platformUtilsService, this.stateService, this.biometricStateService);
        this.sendTokenService = new DefaultSendTokenService(this.globalStateProvider, this.sdkService, this.sendPasswordService);
        this.keyConnectorService = new KeyConnectorService(this.accountService, this.masterPasswordService, this.keyService, this.apiService, this.tokenService, this.logService, this.organizationService, this.keyGenerationService, logoutCallback, this.stateProvider, this.configService, this.registerSdkService, this.accountCryptographicStateService, this.sdkService, this.userDecryptionOptionsService);
        this.twoFactorService = new DefaultTwoFactorService(this.i18nService, this.platformUtilsService, this.globalStateProvider, this.twoFactorApiService);
        this.passwordStrengthService = new PasswordStrengthService();
        this.passwordGenerationService = legacyPasswordGenerationServiceFactory(this.encryptService, this.keyService, this.policyService, this.accountService, this.stateProvider);
        this.authRequestApiService = new DefaultAuthRequestApiService(this.apiService, this.logService);
        this.authRequestService = new AuthRequestService(this.appIdService, this.masterPasswordService, this.keyService, this.encryptService, this.apiService, this.stateProvider, this.authRequestApiService, this.accountService);
        this.billingAccountProfileStateService = new DefaultBillingAccountProfileStateService(this.stateProvider);
        this.taskSchedulerService = new DefaultTaskSchedulerService(this.logService);
        this.devicesApiService = new DevicesApiServiceImplementation(this.apiService);
        this.deviceTrustService = new DeviceTrustService(this.keyGenerationService, this.cryptoFunctionService, this.keyService, this.encryptService, this.appIdService, this.devicesApiService, this.i18nService, this.platformUtilsService, this.stateProvider, this.secureStorageService, this.userDecryptionOptionsService, this.logService, this.configService, this.accountService);
        const passwordPreloginApiService = new PasswordPreloginApiService(this.apiService, this.environmentService);
        this.passwordPreloginService = new DefaultPasswordPreloginService(passwordPreloginApiService);
        const loginStrategyCacheService = new DefaultLoginStrategyCacheService(this.globalStateProvider);
        const loginStrategySessionTimeoutService = new DefaultLoginStrategySessionTimeoutService(this.taskSchedulerService, loginStrategyCacheService, this.logService, this.messagingService, MessageListener.EMPTY);
        this.loginStrategyService = new LoginStrategyService(this.accountService, this.masterPasswordService, this.keyService, this.apiService, this.tokenService, this.appIdService, this.platformUtilsService, this.messagingService, this.logService, this.keyConnectorService, this.environmentService, this.stateService, this.twoFactorService, this.i18nService, this.encryptService, this.passwordStrengthService, this.policyService, this.deviceTrustService, this.authRequestService, this.userDecryptionOptionsService, this.globalStateProvider, this.billingAccountProfileStateService, this.vaultTimeoutSettingsService, this.kdfConfigService, this.configService, this.accountCryptographicStateService, this.passwordPreloginService, this.unlockService, loginStrategyCacheService, loginStrategySessionTimeoutService);
        this.restrictedItemTypesService = new RestrictedItemTypesService(this.accountService, this.organizationService, this.policyService);
        this.cliRestrictedItemTypesService = new CliRestrictedItemTypesService(this.restrictedItemTypesService);
        // FIXME: CLI does not support autofill
        this.autofillSettingsService = new AutofillSettingsService(this.stateProvider, this.policyService, this.accountService, this.restrictedItemTypesService);
        this.cipherEncryptionService = new DefaultCipherEncryptionService(this.sdkService, this.logService);
        this.cipherSdkService = new DefaultCipherSdkService(this.sdkService, this.logService);
        this.cipherService = new CipherService(this.keyService, this.domainSettingsService, this.apiService, this.i18nService, this.searchService, this.autofillSettingsService, this.encryptService, this.cipherFileUploadService, this.configService, this.stateProvider, this.accountService, this.logService, this.cipherEncryptionService, this.messagingService, this.cipherSdkService);
        this.cipherArchiveService = new DefaultCipherArchiveService(this.cipherService, this.apiService, this.billingAccountProfileStateService);
        this.folderService = new FolderService(this.keyService, this.encryptService, this.i18nService, this.cipherService, this.stateProvider);
        this.folderApiService = new FolderApiService(this.folderService, this.apiService);
        this.userVerificationApiService = new UserVerificationApiService(this.apiService);
        this.userVerificationService = new UserVerificationService(this.keyService, this.accountService, this.masterPasswordService, this.i18nService, this.userVerificationApiService, this.userDecryptionOptionsService, this.pinService, this.kdfConfigService, new CliBiometricsService(), this.masterPasswordUnlockService);
        const biometricService = new CliBiometricsService();
        const logoutService = new DefaultLogoutService(this.messagingService);
        const processReloadService = new CliProcessReloadService();
        const systemService = new CliSystemService();
        this.lockService = new DefaultLockService(this.accountService, biometricService, this.vaultTimeoutSettingsService, logoutService, this.messagingService, this.searchService, this.folderService, this.masterPasswordService, this.stateEventRunnerService, this.cipherService, this.authService, systemService, processReloadService, this.logService, this.keyService);
        this.vaultTimeoutService = new VaultTimeoutService(this.accountService, this.platformUtilsService, this.authService, this.vaultTimeoutSettingsService, this.taskSchedulerService, this.logService, this.lockService, undefined);
        this.avatarService = new AvatarService(this.apiService, this.stateProvider);
        this.syncService = new DefaultSyncService(this.masterPasswordService, this.accountService, this.apiService, this.domainSettingsService, this.folderService, this.cipherService, this.keyService, this.collectionService, this.messagingService, this.policyService, this.sendService, this.logService, this.keyConnectorService, this.providerService, this.folderApiService, this.organizationService, this.sendApiService, this.userDecryptionOptionsService, this.avatarService, logoutCallback, this.billingAccountProfileStateService, this.tokenService, this.authService, this.stateProvider, this.securityStateService, this.kdfConfigService, this.accountCryptographicStateService);
        this.totpService = new TotpService(this.sdkService);
        this.importApiService = new ImportApiService(this.apiService);
        this.importMetadataService = new DefaultImportMetadataService(createSystemServiceProvider(new KeyServiceLegacyEncryptorProvider(this.encryptService, this.keyService), this.stateProvider, this.policyService, buildExtensionRegistry(), this.logService, this.platformUtilsService, this.configService));
        this.importService = new ImportService(this.cipherService, this.folderService, this.importApiService, this.i18nService, this.collectionService, this.keyService, this.encryptService, this.keyGenerationService, this.accountService, this.restrictedItemTypesService);
        this.individualExportService = new IndividualVaultExportService(this.folderService, this.cipherService, this.keyGenerationService, this.keyService, this.encryptService, this.cryptoFunctionService, this.kdfConfigService, this.apiService, this.restrictedItemTypesService);
        this.vaultExportApiService = new DefaultVaultExportApiService(this.apiService);
        this.organizationExportService = new OrganizationVaultExportService(this.cipherService, this.vaultExportApiService, this.keyGenerationService, this.keyService, this.encryptService, this.cryptoFunctionService, this.collectionService, this.kdfConfigService, this.restrictedItemTypesService);
        this.exportService = new VaultExportService(this.individualExportService, this.organizationExportService, this.accountService);
        this.userAutoUnlockKeyService = new UserAutoUnlockKeyService(this.keyService);
        this.hibpApiService = new HibpApiService(this.apiService);
        this.auditService = new AuditService(this.cryptoFunctionService, this.apiService, this.hibpApiService);
        this.eventUploadService = new EventUploadService(this.apiService, this.stateProvider, this.logService, this.authService, this.taskSchedulerService);
        this.eventCollectionService = new EventCollectionService(this.cipherService, this.stateProvider, this.organizationService, this.eventUploadService, this.authService, this.accountService);
        this.organizationApiService = new OrganizationApiService(this.apiService, this.syncService);
        this.providerApiService = new ProviderApiService(this.apiService);
        this.organizationUserApiService = new DefaultOrganizationUserApiService(this.apiService);
        this.cipherAuthorizationService = new DefaultCipherAuthorizationService(this.collectionService, this.organizationService, this.accountService);
        this.masterPasswordApiService = new MasterPasswordApiService(this.apiService, this.logService);
        const changeKdfApiService = new DefaultChangeKdfApiService(this.apiService);
        const changeKdfService = new DefaultChangeKdfService(changeKdfApiService, this.sdkService, this.keyService, this.masterPasswordService, this.kdfConfigService);
        this.encryptedMigrator = new DefaultEncryptedMigrator(this.kdfConfigService, changeKdfService, this.logService, this.configService, this.masterPasswordService, this.syncService);
    }
    logout() {
        return service_container_awaiter(this, void 0, void 0, function* () {
            this.authService.logOut(() => {
                /* Do nothing */
            });
            const userId = yield (0,external_rxjs_namespaceObject.firstValueFrom)(account_service_getUserId(this.accountService.activeAccount$));
            yield Promise.all([
                this.eventUploadService.uploadEvents(userId),
                this.keyService.clearKeys(userId),
                this.cipherService.clear(userId),
                this.folderService.clear(userId),
            ]);
            yield this.stateEventRunnerService.handleEvent("logout", userId);
            yield this.stateService.clean({ userId: userId });
            yield this.tokenService.clearTokens(userId);
            yield this.accountService.clean(userId);
            yield this.accountService.switchAccount(null);
            process.env.BW_SESSION = undefined;
        });
    }
    init() {
        return service_container_awaiter(this, void 0, void 0, function* () {
            if (this.inited) {
                this.logService.warning("ServiceContainer.init called more than once");
                return;
            }
            yield this.sdkLoadService.loadAndInit();
            yield this.storageService.init();
            yield this.migrationRunner.run();
            this.containerService.attachToGlobal(global);
            yield this.i18nService.init();
            this.twoFactorService.init();
            const accounts = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.accounts$);
            yield this.tokenService.cleanupTokenStorage(Object.keys(accounts));
            // If a user has a BW_SESSION key stored in their env (not process.env.BW_SESSION),
            // this should set the user key to unlock the vault on init.
            // TODO: ideally, we wouldn't want to do this here but instead only for commands that require the vault to be unlocked
            // as this runs on every command and could be a performance hit
            const activeAccount = yield (0,external_rxjs_namespaceObject.firstValueFrom)(this.accountService.activeAccount$);
            if (activeAccount === null || activeAccount === void 0 ? void 0 : activeAccount.id) {
                yield this.userAutoUnlockKeyService.setUserKeyInMemoryIfAutoUserKeySet(activeAccount.id);
            }
            this.inited = true;
        });
    }
}

;// ../../bitwarden_license/bit-cli/src/service-container.ts
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore


/**
 * Instantiates services and makes them available for dependency injection.
 * Any Bitwarden-licensed services should be registered here.
 */
class ServiceContainer extends service_container_ServiceContainer {
    constructor() {
        super();
        this.organizationAuthRequestApiService = new OrganizationAuthRequestApiService(this.apiService);
        this.organizationAuthRequestService = new OrganizationAuthRequestService(this.organizationAuthRequestApiService, this.keyService, this.encryptService, this.organizationUserApiService, this.accountService);
    }
}

;// ../../bitwarden_license/bit-cli/src/bw.ts
var bw_awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};







function main() {
    return bw_awaiter(this, void 0, void 0, function* () {
        const serviceContainer = new ServiceContainer();
        yield serviceContainer.init();
        yield registerOssPrograms(serviceContainer);
        yield registerBitPrograms(serviceContainer);
        const serveConfigurator = new BitServeConfigurator(serviceContainer);
        new ServeProgram(serviceContainer, serveConfigurator).register();
        external_commander_namespaceObject.program.parse(process.argv);
    });
}
// Node does not support top-level await statements until ES2022, esnext, etc which we don't use yet
// eslint-disable-next-line @typescript-eslint/no-floating-promises
main();

/******/ })()
;
//# sourceMappingURL=bw.js.map