forked from trent_larson/crowd-funder-for-time-pwa
Merge branch 'master' into claimview-fullfills-offer
This commit is contained in:
164
src/libs/util.ts
164
src/libs/util.ts
@@ -33,6 +33,7 @@ import { logger } from "../utils/logger";
|
||||
import { PlatformServiceFactory } from "../services/PlatformServiceFactory";
|
||||
import { IIdentifier } from "@veramo/core";
|
||||
import { DEFAULT_ROOT_DERIVATION_PATH } from "./crypto";
|
||||
import { UNNAMED_PERSON } from "@/constants/entities";
|
||||
|
||||
// Consolidate this with src/utils/PlatformServiceMixin.mapQueryResultToValues
|
||||
function mapQueryResultToValues(
|
||||
@@ -227,7 +228,7 @@ export const nameForContact = (
|
||||
): string => {
|
||||
return (
|
||||
(contact?.name as string) ||
|
||||
(capitalize ? "This" : "this") + " unnamed user"
|
||||
(capitalize ? "This" : "this") + " " + UNNAMED_PERSON
|
||||
);
|
||||
};
|
||||
|
||||
@@ -648,57 +649,64 @@ export const retrieveAllAccountsMetadata = async (): Promise<
|
||||
return result;
|
||||
};
|
||||
|
||||
export const DUPLICATE_ACCOUNT_ERROR = "Cannot import duplicate account.";
|
||||
|
||||
/**
|
||||
* Saves a new identity to both SQL and Dexie databases
|
||||
* Saves a new identity to SQL database
|
||||
*/
|
||||
export async function saveNewIdentity(
|
||||
identity: IIdentifier,
|
||||
mnemonic: string,
|
||||
derivationPath: string,
|
||||
): Promise<void> {
|
||||
try {
|
||||
// add to the new sql db
|
||||
const platformService = await getPlatformService();
|
||||
// add to the new sql db
|
||||
const platformService = await getPlatformService();
|
||||
|
||||
const secrets = await platformService.dbQuery(
|
||||
`SELECT secretBase64 FROM secret`,
|
||||
);
|
||||
if (!secrets?.values?.length || !secrets.values[0]?.length) {
|
||||
throw new Error(
|
||||
"No initial encryption supported. We recommend you clear your data and start over.",
|
||||
);
|
||||
}
|
||||
// Check if account already exists before attempting to save
|
||||
const existingAccount = await platformService.dbQuery(
|
||||
"SELECT did FROM accounts WHERE did = ?",
|
||||
[identity.did],
|
||||
);
|
||||
|
||||
const secretBase64 = secrets.values[0][0] as string;
|
||||
|
||||
const secret = base64ToArrayBuffer(secretBase64);
|
||||
const identityStr = JSON.stringify(identity);
|
||||
const encryptedIdentity = await simpleEncrypt(identityStr, secret);
|
||||
const encryptedMnemonic = await simpleEncrypt(mnemonic, secret);
|
||||
const encryptedIdentityBase64 = arrayBufferToBase64(encryptedIdentity);
|
||||
const encryptedMnemonicBase64 = arrayBufferToBase64(encryptedMnemonic);
|
||||
|
||||
const sql = `INSERT INTO accounts (dateCreated, derivationPath, did, identityEncrBase64, mnemonicEncrBase64, publicKeyHex)
|
||||
VALUES (?, ?, ?, ?, ?, ?)`;
|
||||
const params = [
|
||||
new Date().toISOString(),
|
||||
derivationPath,
|
||||
identity.did,
|
||||
encryptedIdentityBase64,
|
||||
encryptedMnemonicBase64,
|
||||
identity.keys[0].publicKeyHex,
|
||||
];
|
||||
await platformService.dbExec(sql, params);
|
||||
|
||||
await platformService.updateDefaultSettings({ activeDid: identity.did });
|
||||
|
||||
await platformService.insertDidSpecificSettings(identity.did);
|
||||
} catch (error) {
|
||||
logger.error("Failed to update default settings:", error);
|
||||
if (existingAccount?.values?.length) {
|
||||
throw new Error(
|
||||
"Failed to set default settings. Please try again or restart the app.",
|
||||
`Account with DID ${identity.did} already exists. ${DUPLICATE_ACCOUNT_ERROR}`,
|
||||
);
|
||||
}
|
||||
|
||||
const secrets = await platformService.dbQuery(
|
||||
`SELECT secretBase64 FROM secret`,
|
||||
);
|
||||
if (!secrets?.values?.length || !secrets.values[0]?.length) {
|
||||
throw new Error(
|
||||
"No initial encryption supported. We recommend you clear your data and start over.",
|
||||
);
|
||||
}
|
||||
|
||||
const secretBase64 = secrets.values[0][0] as string;
|
||||
|
||||
const secret = base64ToArrayBuffer(secretBase64);
|
||||
const identityStr = JSON.stringify(identity);
|
||||
const encryptedIdentity = await simpleEncrypt(identityStr, secret);
|
||||
const encryptedMnemonic = await simpleEncrypt(mnemonic, secret);
|
||||
const encryptedIdentityBase64 = arrayBufferToBase64(encryptedIdentity);
|
||||
const encryptedMnemonicBase64 = arrayBufferToBase64(encryptedMnemonic);
|
||||
|
||||
const sql = `INSERT INTO accounts (dateCreated, derivationPath, did, identityEncrBase64, mnemonicEncrBase64, publicKeyHex)
|
||||
VALUES (?, ?, ?, ?, ?, ?)`;
|
||||
const params = [
|
||||
new Date().toISOString(),
|
||||
derivationPath,
|
||||
identity.did,
|
||||
encryptedIdentityBase64,
|
||||
encryptedMnemonicBase64,
|
||||
identity.keys[0].publicKeyHex,
|
||||
];
|
||||
await platformService.dbExec(sql, params);
|
||||
|
||||
await platformService.updateDefaultSettings({ activeDid: identity.did });
|
||||
|
||||
await platformService.insertNewDidIntoSettings(identity.did);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -989,7 +997,7 @@ export async function importFromMnemonic(
|
||||
|
||||
try {
|
||||
// First, ensure the DID-specific settings record exists
|
||||
await platformService.insertDidSpecificSettings(newId.did);
|
||||
await platformService.insertNewDidIntoSettings(newId.did);
|
||||
|
||||
// Then update with Test User #0 specific settings
|
||||
await platformService.updateDidSpecificSettings(newId.did, {
|
||||
@@ -1008,13 +1016,16 @@ export async function importFromMnemonic(
|
||||
const firstName = settings[0];
|
||||
const isRegistered = settings[1];
|
||||
|
||||
logger.info("[importFromMnemonic] Test User #0 settings verification", {
|
||||
did: newId.did,
|
||||
firstName,
|
||||
isRegistered,
|
||||
expectedFirstName: "User Zero",
|
||||
expectedIsRegistered: true,
|
||||
});
|
||||
logger.debug(
|
||||
"[importFromMnemonic] Test User #0 settings verification",
|
||||
{
|
||||
did: newId.did,
|
||||
firstName,
|
||||
isRegistered,
|
||||
expectedFirstName: "User Zero",
|
||||
expectedIsRegistered: true,
|
||||
},
|
||||
);
|
||||
|
||||
// If settings weren't saved correctly, try individual updates
|
||||
if (firstName !== "User Zero" || isRegistered !== 1) {
|
||||
@@ -1040,7 +1051,7 @@ export async function importFromMnemonic(
|
||||
|
||||
if (retryResult?.values?.length) {
|
||||
const retrySettings = retryResult.values[0];
|
||||
logger.info(
|
||||
logger.debug(
|
||||
"[importFromMnemonic] Test User #0 settings after retry",
|
||||
{
|
||||
firstName: retrySettings[0],
|
||||
@@ -1063,3 +1074,58 @@ export async function importFromMnemonic(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an account with the given DID already exists in the database
|
||||
*
|
||||
* @param did - The DID to check for duplicates
|
||||
* @returns Promise<boolean> - True if account already exists, false otherwise
|
||||
* @throws Error if database query fails
|
||||
*/
|
||||
export async function checkForDuplicateAccount(did: string): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Checks if an account with the given DID already exists in the database
|
||||
*
|
||||
* @param mnemonic - The mnemonic phrase to derive DID from
|
||||
* @param derivationPath - The derivation path to use
|
||||
* @returns Promise<boolean> - True if account already exists, false otherwise
|
||||
* @throws Error if database query fails
|
||||
*/
|
||||
export async function checkForDuplicateAccount(
|
||||
mnemonic: string,
|
||||
derivationPath: string,
|
||||
): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Implementation of checkForDuplicateAccount with overloaded signatures
|
||||
*/
|
||||
export async function checkForDuplicateAccount(
|
||||
didOrMnemonic: string,
|
||||
derivationPath?: string,
|
||||
): Promise<boolean> {
|
||||
let didToCheck: string;
|
||||
|
||||
if (derivationPath) {
|
||||
// Derive the DID from mnemonic and derivation path
|
||||
const [address, privateHex, publicHex] = deriveAddress(
|
||||
didOrMnemonic.trim().toLowerCase(),
|
||||
derivationPath,
|
||||
);
|
||||
|
||||
const newId = newIdentifier(address, privateHex, publicHex, derivationPath);
|
||||
didToCheck = newId.did;
|
||||
} else {
|
||||
// Use the provided DID directly
|
||||
didToCheck = didOrMnemonic;
|
||||
}
|
||||
|
||||
// Check if an account with this DID already exists
|
||||
const platformService = await getPlatformService();
|
||||
const existingAccount = await platformService.dbQuery(
|
||||
"SELECT did FROM accounts WHERE did = ?",
|
||||
[didToCheck],
|
||||
);
|
||||
|
||||
return (existingAccount?.values?.length ?? 0) > 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user