refactor: consolidate duplicate account checking logic into unified utility

- Extract checkForDuplicateAccount methods from ImportAccountView and ImportDerivedAccountView
- Create unified utility function in src/libs/util.ts with TypeScript overloads
- Support both direct DID checking and mnemonic+derivation path checking
- Improve error handling with centralized logging via PlatformServiceFactory
- Add comprehensive JSDoc documentation for both function overloads
- Remove unused imports (deriveAddress, newIdentifier) from ImportAccountView

The utility function now provides a clean API:
- checkForDuplicateAccount(did) - for direct DID checking
- checkForDuplicateAccount(mnemonic, derivationPath) - for derivation + checking

Both components maintain identical functionality while using centralized logic.
This commit is contained in:
Jose Olarte III
2025-09-01 19:36:01 +08:00
parent d339f1a274
commit 25e37cc415
3 changed files with 77 additions and 67 deletions

View File

@@ -87,12 +87,12 @@ import { Component, Vue } from "vue-facing-decorator";
import { Router } from "vue-router";
import { AppString, NotificationIface } from "../constants/app";
import { DEFAULT_ROOT_DERIVATION_PATH } from "../libs/crypto";
import {
DEFAULT_ROOT_DERIVATION_PATH,
deriveAddress,
newIdentifier,
} from "../libs/crypto";
import { retrieveAccountCount, importFromMnemonic } from "../libs/util";
retrieveAccountCount,
importFromMnemonic,
checkForDuplicateAccount,
} from "../libs/util";
import { PlatformServiceMixin } from "@/utils/PlatformServiceMixin";
import { createNotifyHelpers, TIMEOUTS } from "@/utils/notify";
import { NOTIFY_DUPLICATE_ACCOUNT_IMPORT } from "@/constants/notifications";
@@ -204,7 +204,10 @@ export default class ImportAccountView extends Vue {
try {
// Check for duplicate account before importing
const isDuplicate = await this.checkForDuplicateAccount();
const isDuplicate = await checkForDuplicateAccount(
this.mnemonic,
this.derivationPath,
);
if (isDuplicate) {
this.notify.warning(
NOTIFY_DUPLICATE_ACCOUNT_IMPORT.message,
@@ -259,43 +262,5 @@ export default class ImportAccountView extends Vue {
);
}
}
/**
* Checks if the account to be imported already exists
*
* Derives the DID from the mnemonic and checks if it exists in the database
* @returns Promise<boolean> - True if account already exists, false otherwise
*/
private async checkForDuplicateAccount(): Promise<boolean> {
try {
// Derive the address and create the identifier to get the DID
const [address, privateHex, publicHex] = deriveAddress(
this.mnemonic.trim().toLowerCase(),
this.derivationPath,
);
const newId = newIdentifier(
address,
publicHex,
privateHex,
this.derivationPath,
);
const didToCheck = newId.did;
// Check if an account with this DID already exists
const existingAccount = await this.$query(
"SELECT did FROM accounts WHERE did = ?",
[didToCheck],
);
return existingAccount?.values?.length > 0;
} catch (error) {
// If we can't check for duplicates (e.g., invalid mnemonic),
// let the import process handle the error
this.$logError("Error checking for duplicate account: " + error);
// Return false to let the import process continue and handle the error
return false;
}
}
}
</script>

View File

@@ -83,6 +83,7 @@ import {
retrieveAllAccountsMetadata,
retrieveFullyDecryptedAccount,
saveNewIdentity,
checkForDuplicateAccount,
} from "../libs/util";
import { logger } from "../utils/logger";
import { Account, AccountEncrypted } from "../db/tables/accounts";
@@ -172,7 +173,7 @@ export default class ImportAccountView extends Vue {
try {
// Check for duplicate account before creating
const isDuplicate = await this.checkForDuplicateAccount(newId.did);
const isDuplicate = await checkForDuplicateAccount(newId.did);
if (isDuplicate) {
this.notify.warning(
"This derived account already exists. Please try a different derivation path.",
@@ -202,27 +203,5 @@ export default class ImportAccountView extends Vue {
this.notify.error(NOTIFY_ACCOUNT_DERIVATION_ERROR.message, TIMEOUTS.LONG);
}
}
/**
* Checks if the account to be created already exists
*
* @param did - The DID to check for duplicates
* @returns Promise<boolean> - True if account already exists, false otherwise
*/
private async checkForDuplicateAccount(did: string): Promise<boolean> {
try {
// Check if an account with this DID already exists
const existingAccount = await this.$query(
"SELECT did FROM accounts WHERE did = ?",
[did],
);
return existingAccount?.values?.length > 0;
} catch (error) {
// If we can't check for duplicates, let the save process handle the error
this.$logError("Error checking for duplicate account: " + error);
return false;
}
}
}
</script>