7cf52319530ae65af85ef36b739930bfa7e23e4b2a8a0b0675b845ee6f206bdb.json raw
1 {"ast":null,"code":"import _asyncToGenerator from \"/home/mleku/src/orly.dev/next/signer/node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js\";\nimport { SyncFlow } from './types';\nimport { CryptoHelper } from '@common';\nimport { Buffer } from 'buffer';\nimport { addIdentity, deleteIdentity, switchIdentity } from './related/identity';\nimport { deletePermission } from './related/permission';\nimport { createNewVault, deleteVault, unlockVault } from './related/vault';\nimport { addRelay, deleteRelay, updateRelay } from './related/relay';\nimport { addNwcConnection, deleteNwcConnection, updateNwcConnectionBalance } from './related/nwc';\nimport { addCashuMint, deleteCashuMint, updateCashuMintProofs } from './related/cashu';\nimport * as i0 from \"@angular/core\";\nexport let StorageService = /*#__PURE__*/(() => {\n class StorageService {\n latestVersion = 2;\n isInitialized = false;\n #browserSessionHandler;\n #browserSyncYesHandler;\n #browserSyncNoHandler;\n #signerMetaHandler;\n initialize(config) {\n if (this.isInitialized) {\n return;\n }\n this.#browserSessionHandler = config.browserSessionHandler;\n this.#browserSyncYesHandler = config.browserSyncYesHandler;\n this.#browserSyncNoHandler = config.browserSyncNoHandler;\n this.#signerMetaHandler = config.signerMetaHandler;\n this.isInitialized = true;\n }\n enableBrowserSyncFlow(flow) {\n var _this = this;\n return _asyncToGenerator(function* () {\n _this.assureIsInitialized();\n _this.#signerMetaHandler.setSyncFlow(flow);\n })();\n }\n loadExtensionSettings() {\n var _this2 = this;\n return _asyncToGenerator(function* () {\n _this2.assureIsInitialized();\n const data = yield _this2.#signerMetaHandler.loadFullData();\n if (Object.keys(data).length === 0) {\n // No data available yet.\n return undefined;\n }\n _this2.#signerMetaHandler.setFullData(data);\n return data;\n })();\n }\n /** @deprecated Use loadExtensionSettings instead */\n loadSignerMetaData() {\n var _this3 = this;\n return _asyncToGenerator(function* () {\n return _this3.loadExtensionSettings();\n })();\n }\n loadVaultSession() {\n var _this4 = this;\n return _asyncToGenerator(function* () {\n _this4.assureIsInitialized();\n const data = yield _this4.#browserSessionHandler.loadFullData();\n if (Object.keys(data).length === 0) {\n // No data available yet (e.g. because the vault was not unlocked).\n return undefined;\n }\n // Set the existing data for in-memory usage.\n _this4.#browserSessionHandler.setFullData(data);\n return data;\n })();\n }\n /** @deprecated Use loadVaultSession instead */\n loadBrowserSessionData() {\n var _this5 = this;\n return _asyncToGenerator(function* () {\n return _this5.loadVaultSession();\n })();\n }\n /**\n * Load and migrate the encrypted vault data. If no data is available yet,\n * the returned object is undefined.\n */\n loadAndMigrateEncryptedVault() {\n var _this6 = this;\n return _asyncToGenerator(function* () {\n _this6.assureIsInitialized();\n const unmigratedEncryptedVault = yield _this6.getBrowserSyncHandler().loadUnmigratedData();\n const {\n encryptedVault,\n migrationWasPerformed\n } = _this6.#migrateEncryptedVault(unmigratedEncryptedVault);\n if (!encryptedVault) {\n // Nothing to do at this point.\n return undefined;\n }\n // There is data. Check, if it was migrated.\n if (migrationWasPerformed) {\n // Persist the migrated data back to the browser sync storage.\n _this6.getBrowserSyncHandler().saveAndSetFullData(encryptedVault);\n } else {\n // Set the data for in-memory usage.\n _this6.getBrowserSyncHandler().setFullData(encryptedVault);\n }\n return encryptedVault;\n })();\n }\n /** @deprecated Use loadAndMigrateEncryptedVault instead */\n loadAndMigrateBrowserSyncData() {\n var _this7 = this;\n return _asyncToGenerator(function* () {\n return _this7.loadAndMigrateEncryptedVault();\n })();\n }\n deleteVault() {\n var _this8 = this;\n return _asyncToGenerator(function* (doNotSetIsInitializedToFalse = false) {\n yield deleteVault.call(_this8, doNotSetIsInitializedToFalse);\n }).apply(this, arguments);\n }\n resetExtension() {\n var _this9 = this;\n return _asyncToGenerator(function* () {\n _this9.assureIsInitialized();\n yield _this9.getBrowserSyncHandler().clearData();\n yield _this9.getBrowserSessionHandler().clearData();\n yield _this9.getSignerMetaHandler().clearData([]);\n _this9.isInitialized = false;\n })();\n }\n lockVault() {\n var _this0 = this;\n return _asyncToGenerator(function* () {\n _this0.assureIsInitialized();\n yield _this0.getBrowserSessionHandler().clearData();\n _this0.getBrowserSessionHandler().clearInMemoryData();\n // Note: We don't set isInitialized = false here because the sync data\n // (encrypted vault) is still loaded and we need it to unlock again\n })();\n }\n unlockVault(password) {\n var _this1 = this;\n return _asyncToGenerator(function* () {\n yield unlockVault.call(_this1, password);\n })();\n }\n createNewVault(password) {\n var _this10 = this;\n return _asyncToGenerator(function* () {\n yield createNewVault.call(_this10, password);\n })();\n }\n addIdentity(data) {\n var _this11 = this;\n return _asyncToGenerator(function* () {\n yield addIdentity.call(_this11, data);\n })();\n }\n deleteIdentity(identityId) {\n var _this12 = this;\n return _asyncToGenerator(function* () {\n yield deleteIdentity.call(_this12, identityId);\n })();\n }\n switchIdentity(identityId) {\n var _this13 = this;\n return _asyncToGenerator(function* () {\n yield switchIdentity.call(_this13, identityId);\n })();\n }\n deletePermission(permissionId) {\n var _this14 = this;\n return _asyncToGenerator(function* () {\n yield deletePermission.call(_this14, permissionId);\n })();\n }\n addRelay(data) {\n var _this15 = this;\n return _asyncToGenerator(function* () {\n yield addRelay.call(_this15, data);\n })();\n }\n deleteRelay(relayId) {\n var _this16 = this;\n return _asyncToGenerator(function* () {\n yield deleteRelay.call(_this16, relayId);\n })();\n }\n updateRelay(relayClone) {\n var _this17 = this;\n return _asyncToGenerator(function* () {\n yield updateRelay.call(_this17, relayClone);\n })();\n }\n addNwcConnection(data) {\n var _this18 = this;\n return _asyncToGenerator(function* () {\n yield addNwcConnection.call(_this18, data);\n })();\n }\n deleteNwcConnection(connectionId) {\n var _this19 = this;\n return _asyncToGenerator(function* () {\n yield deleteNwcConnection.call(_this19, connectionId);\n })();\n }\n updateNwcConnectionBalance(connectionId, balanceMillisats) {\n var _this20 = this;\n return _asyncToGenerator(function* () {\n yield updateNwcConnectionBalance.call(_this20, connectionId, balanceMillisats);\n })();\n }\n addCashuMint(data) {\n var _this21 = this;\n return _asyncToGenerator(function* () {\n return yield addCashuMint.call(_this21, data);\n })();\n }\n deleteCashuMint(mintId) {\n var _this22 = this;\n return _asyncToGenerator(function* () {\n yield deleteCashuMint.call(_this22, mintId);\n })();\n }\n updateCashuMintProofs(mintId, proofs) {\n var _this23 = this;\n return _asyncToGenerator(function* () {\n yield updateCashuMintProofs.call(_this23, mintId, proofs);\n })();\n }\n exportVault() {\n this.assureIsInitialized();\n const vaultJson = JSON.stringify(this.getBrowserSyncHandler().encryptedVault, undefined, 4);\n return vaultJson;\n }\n importVault(allegedEncryptedVault) {\n var _this24 = this;\n return _asyncToGenerator(function* () {\n _this24.assureIsInitialized();\n const isValidData = _this24.#allegedEncryptedVaultIsValid(allegedEncryptedVault);\n if (!isValidData) {\n throw new Error('The imported data is not valid.');\n }\n yield _this24.getBrowserSyncHandler().saveAndSetFullData(allegedEncryptedVault);\n })();\n }\n getBrowserSyncHandler() {\n this.assureIsInitialized();\n switch (this.#signerMetaHandler.extensionSettings?.syncFlow) {\n case SyncFlow.NO_SYNC:\n return this.#browserSyncNoHandler;\n case SyncFlow.BROWSER_SYNC:\n default:\n return this.#browserSyncYesHandler;\n }\n }\n getBrowserSessionHandler() {\n this.assureIsInitialized();\n return this.#browserSessionHandler;\n }\n getSignerMetaHandler() {\n this.assureIsInitialized();\n return this.#signerMetaHandler;\n }\n /**\n * Get the current sync flow setting.\n * Returns NO_SYNC if not initialized or no setting found.\n */\n getSyncFlow() {\n if (!this.isInitialized || !this.#signerMetaHandler?.extensionSettings) {\n return SyncFlow.NO_SYNC;\n }\n return this.#signerMetaHandler.extensionSettings.syncFlow ?? SyncFlow.NO_SYNC;\n }\n /**\n * Throws an exception if the service is not initialized.\n */\n assureIsInitialized() {\n if (!this.isInitialized) {\n throw new Error('StorageService is not initialized. Please call \"initialize(...)\" before doing anything else.');\n }\n }\n encrypt(value) {\n var _this25 = this;\n return _asyncToGenerator(function* () {\n const vaultSession = _this25.getBrowserSessionHandler().vaultSession;\n if (!vaultSession) {\n throw new Error('Vault session is undefined.');\n }\n // v2: Use pre-derived key directly with AES-GCM\n if (vaultSession.vaultKey) {\n return _this25.encryptV2(value, vaultSession.iv, vaultSession.vaultKey);\n }\n // v1: Use PBKDF2 with password\n if (!vaultSession.vaultPassword) {\n throw new Error('No vault password or key available.');\n }\n return CryptoHelper.encrypt(value, vaultSession.iv, vaultSession.vaultPassword);\n })();\n }\n /**\n * v2 encryption: Use pre-derived key bytes directly with AES-GCM (no key derivation)\n */\n encryptV2(text, ivBase64, keyBase64) {\n return _asyncToGenerator(function* () {\n const keyBytes = Buffer.from(keyBase64, 'base64');\n const iv = Buffer.from(ivBase64, 'base64');\n const key = yield crypto.subtle.importKey('raw', keyBytes, {\n name: 'AES-GCM'\n }, false, ['encrypt']);\n const cipherText = yield crypto.subtle.encrypt({\n name: 'AES-GCM',\n iv\n }, key, new TextEncoder().encode(text));\n return Buffer.from(cipherText).toString('base64');\n })();\n }\n decrypt(value, returnType) {\n var _this26 = this;\n return _asyncToGenerator(function* () {\n const vaultSession = _this26.getBrowserSessionHandler().vaultSession;\n if (!vaultSession) {\n throw new Error('Vault session is undefined.');\n }\n // v2: Use pre-derived key directly with AES-GCM\n if (vaultSession.vaultKey) {\n const decryptedValue = yield _this26.decryptV2(value, vaultSession.iv, vaultSession.vaultKey);\n return _this26.parseDecryptedValue(decryptedValue, returnType);\n }\n // v1: Use PBKDF2 with password\n if (!vaultSession.vaultPassword) {\n throw new Error('No vault password or key available.');\n }\n return _this26.decryptWithLockedVault(value, returnType, vaultSession.iv, vaultSession.vaultPassword);\n })();\n }\n /**\n * v2 decryption: Use pre-derived key bytes directly with AES-GCM (no key derivation)\n */\n decryptV2(encryptedBase64, ivBase64, keyBase64) {\n return _asyncToGenerator(function* () {\n const keyBytes = Buffer.from(keyBase64, 'base64');\n const iv = Buffer.from(ivBase64, 'base64');\n const cipherText = Buffer.from(encryptedBase64, 'base64');\n const key = yield crypto.subtle.importKey('raw', keyBytes, {\n name: 'AES-GCM'\n }, false, ['decrypt']);\n const decrypted = yield crypto.subtle.decrypt({\n name: 'AES-GCM',\n iv\n }, key, cipherText);\n return new TextDecoder().decode(decrypted);\n })();\n }\n /**\n * Parse a decrypted string value into the desired type\n */\n parseDecryptedValue(decryptedValue, returnType) {\n switch (returnType) {\n case 'number':\n return parseInt(decryptedValue);\n case 'boolean':\n return decryptedValue === 'true';\n case 'string':\n default:\n return decryptedValue;\n }\n }\n /**\n * v1: Decrypt with locked vault using password (PBKDF2)\n */\n decryptWithLockedVault(value, returnType, iv, password) {\n var _this27 = this;\n return _asyncToGenerator(function* () {\n const decryptedValue = yield CryptoHelper.decrypt(value, iv, password);\n return _this27.parseDecryptedValue(decryptedValue, returnType);\n })();\n }\n /**\n * v2: Decrypt with locked vault using pre-derived key (Argon2id)\n */\n decryptWithLockedVaultV2(value, returnType, iv, keyBase64) {\n var _this28 = this;\n return _asyncToGenerator(function* () {\n const decryptedValue = yield _this28.decryptV2(value, iv, keyBase64);\n return _this28.parseDecryptedValue(decryptedValue, returnType);\n })();\n }\n /**\n * Migrate the encrypted vault to the latest version.\n */\n #migrateEncryptedVault(encryptedVault) {\n if (Object.keys(encryptedVault).length === 0) {\n // First run. There is no encrypted vault yet.\n return {\n encryptedVault: undefined,\n migrationWasPerformed: false\n };\n }\n // Will be implemented if migration is required.\n return {\n encryptedVault: encryptedVault,\n migrationWasPerformed: false\n };\n }\n #allegedEncryptedVaultIsValid(data) {\n if (typeof data.iv === 'undefined') {\n return false;\n }\n if (typeof data.version !== 'number') {\n return false;\n }\n if (typeof data.vaultHash === 'undefined') {\n return false;\n }\n if (typeof data.selectedIdentityId === 'undefined') {\n return false;\n }\n if (typeof data.identities === 'undefined' || !Array.isArray(data.identities)) {\n return false;\n }\n if (typeof data.permissions === 'undefined' || !Array.isArray(data.permissions)) {\n return false;\n }\n if (typeof data.relays === 'undefined' || !Array.isArray(data.relays)) {\n return false;\n }\n return true;\n }\n static ɵfac = function StorageService_Factory(__ngFactoryType__) {\n return new (__ngFactoryType__ || StorageService)();\n };\n static ɵprov = /*@__PURE__*/i0.ɵɵdefineInjectable({\n token: StorageService,\n factory: StorageService.ɵfac,\n providedIn: 'root'\n });\n }\n return StorageService;\n})();","map":null,"metadata":{},"sourceType":"module","externalDependencies":[]}