From bc274bdf7ffa4217d7064d131783132aee5f2de7 Mon Sep 17 00:00:00 2001 From: Matthew Raymer Date: Wed, 28 May 2025 08:52:09 +0000 Subject: [PATCH] fix(types): improve account type safety and metadata handling - Change retrieveAllAccountsMetadata to return Account[] instead of AccountEncrypted[] to better reflect its purpose of returning non-sensitive metadata - Update ImportDerivedAccountView to use Account type and group by derivation path - Update retrieveAllFullyDecryptedAccounts to use AccountEncrypted type for encrypted data - Fix import path for Account type in ImportDerivedAccountView This change improves type safety by making it explicit which functions handle encrypted data vs metadata, and ensures consistent handling of account data across the application. The metadata functions now correctly strip sensitive fields while functions that need encrypted data maintain access to those fields. --- src/libs/util.ts | 14 ++++++-------- src/views/ImportDerivedAccountView.vue | 22 ++++++++++++---------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/libs/util.ts b/src/libs/util.ts index 7d745679..0af2bb47 100644 --- a/src/libs/util.ts +++ b/src/libs/util.ts @@ -543,16 +543,14 @@ export const retrieveAccountMetadata = async ( return result; }; -export const retrieveAllAccountsMetadata = async (): Promise< - AccountEncrypted[] -> => { +export const retrieveAllAccountsMetadata = async (): Promise => { const platformService = PlatformServiceFactory.getInstance(); const dbAccounts = await platformService.dbQuery(`SELECT * FROM accounts`); const accounts = databaseUtil.mapQueryResultToValues(dbAccounts) as Account[]; let result = accounts.map((account) => { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { identity, mnemonic, ...metadata } = account; - return metadata; + return metadata as Account; }); if (USE_DEXIE_DB) { // one of the few times we use accountsDBPromise directly; try to avoid more usage @@ -561,7 +559,7 @@ export const retrieveAllAccountsMetadata = async (): Promise< result = array.map((account) => { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { identity, mnemonic, ...metadata } = account; - return metadata; + return metadata as Account; }); } return result; @@ -620,16 +618,16 @@ export const retrieveFullyDecryptedAccount = async ( // let's try and eliminate this export const retrieveAllFullyDecryptedAccounts = async (): Promise< - Array + Array > => { const platformService = PlatformServiceFactory.getInstance(); const queryResult = await platformService.dbQuery("SELECT * FROM accounts"); let allAccounts = databaseUtil.mapQueryResultToValues( queryResult, - ) as unknown as Account[]; + ) as unknown as AccountEncrypted[]; if (USE_DEXIE_DB) { const accountsDB = await accountsDBPromise; - allAccounts = await accountsDB.accounts.toArray(); + allAccounts = await accountsDB.accounts.toArray() as AccountEncrypted[]; } return allAccounts; }; diff --git a/src/views/ImportDerivedAccountView.vue b/src/views/ImportDerivedAccountView.vue index 9dff2998..2561d659 100644 --- a/src/views/ImportDerivedAccountView.vue +++ b/src/views/ImportDerivedAccountView.vue @@ -83,7 +83,7 @@ import { MASTER_SETTINGS_KEY } from "../db/tables/settings"; import * as databaseUtil from "../db/databaseUtil"; import { retrieveAllAccountsMetadata } from "../libs/util"; import { logger } from "../utils/logger"; -import { AccountEncrypted } from "@/db/tables/accounts"; +import { Account } from "../db/tables/accounts"; import { PlatformServiceFactory } from "@/services/PlatformServiceFactory"; import { USE_DEXIE_DB } from "@/constants/app"; @Component({ @@ -98,18 +98,20 @@ export default class ImportAccountView extends Vue { selectedArrayFirstDid = ""; async mounted() { - const accounts: AccountEncrypted[] = await retrieveAllAccountsMetadata(); + const accounts: Account[] = await retrieveAllAccountsMetadata(); const seedDids: Record> = {}; accounts.forEach((account) => { - const mnemonicMaybeEncrypted = - account.mnemonic || account.mnemonicEncrBase64; - if (mnemonicMaybeEncrypted) { - const prevDids: Array = seedDids[mnemonicMaybeEncrypted] || []; - seedDids[mnemonicMaybeEncrypted] = prevDids.concat([account.did]); + // Since we're only getting metadata, we can't check mnemonic + // Instead, we'll group by derivation path + if (account.derivationPath) { + const prevDids: Array = seedDids[account.derivationPath] || []; + seedDids[account.derivationPath] = prevDids.concat([account.did]); } }); this.didArrays = Object.values(seedDids); - this.selectedArrayFirstDid = this.didArrays[0][0]; + if (this.didArrays.length > 0) { + this.selectedArrayFirstDid = this.didArrays[0][0]; + } } public onCancelClick() { @@ -133,13 +135,13 @@ export default class ImportAccountView extends Vue { ); let allMatchingAccounts = databaseUtil.mapQueryResultToValues( queryResult, - ) as unknown as AccountEncrypted[]; + ) as unknown as Account[]; if (USE_DEXIE_DB) { const accountsDB = await accountsDBPromise; // let's match derived accounts differently so we don't need the private info allMatchingAccounts = (await accountsDB.accounts .where("did") .anyOf(...selectedArray) - .toArray()) as AccountEncrypted[]; + .toArray()) as Account[]; } const accountWithMaxDeriv = allMatchingAccounts[0]; allMatchingAccounts.slice(1).forEach((account) => {