From a082469a013a036a4e49e4040e44d91583c4cdf5 Mon Sep 17 00:00:00 2001
From: Trent Larson <trent@trentlarson.com>
Date: Tue, 10 Jun 2025 20:51:22 -0600
Subject: [PATCH] fix creation of did-specific settings (with a rename)

---
 src/components/OnboardingDialog.vue    |  4 ++--
 src/db/databaseUtil.ts                 | 16 +++++++++++++++-
 src/libs/util.ts                       |  7 +++++--
 src/views/AccountViewView.vue          |  4 ++--
 src/views/ContactsView.vue             | 17 ++++++-----------
 src/views/HelpView.vue                 |  2 +-
 src/views/HomeView.vue                 |  4 ++--
 src/views/ImportDerivedAccountView.vue | 17 +++++------------
 src/views/NewActivityView.vue          | 12 ++++++------
 9 files changed, 44 insertions(+), 39 deletions(-)

diff --git a/src/components/OnboardingDialog.vue b/src/components/OnboardingDialog.vue
index 01d53d6c..5e7489ae 100644
--- a/src/components/OnboardingDialog.vue
+++ b/src/components/OnboardingDialog.vue
@@ -259,7 +259,7 @@ export default class OnboardingDialog extends Vue {
     this.visible = true;
     if (this.page === OnboardPage.Create) {
       // we'll assume that they've been through all the other pages
-      await databaseUtil.updateAccountSettings(this.activeDid, {
+      await databaseUtil.updateDidSpecificSettings(this.activeDid, {
         finishedOnboarding: true,
       });
       if (USE_DEXIE_DB) {
@@ -273,7 +273,7 @@ export default class OnboardingDialog extends Vue {
   async onClickClose(done?: boolean, goHome?: boolean) {
     this.visible = false;
     if (done) {
-      await databaseUtil.updateAccountSettings(this.activeDid, {
+      await databaseUtil.updateDidSpecificSettings(this.activeDid, {
         finishedOnboarding: true,
       });
       if (USE_DEXIE_DB) {
diff --git a/src/db/databaseUtil.ts b/src/db/databaseUtil.ts
index d68926fe..f5de35c0 100644
--- a/src/db/databaseUtil.ts
+++ b/src/db/databaseUtil.ts
@@ -37,7 +37,20 @@ export async function updateDefaultSettings(
   }
 }
 
-export async function updateAccountSettings(
+export async function insertDidSpecificSettings(
+  did: string,
+  settings: Partial<Settings> = {},
+): Promise<boolean> {
+  const platform = PlatformServiceFactory.getInstance();
+  const { sql, params } = generateInsertStatement(
+    { ...settings, accountDid: did }, // make sure accountDid is set to the given value
+    "settings",
+  );
+  const result = await platform.dbExec(sql, params);
+  return result.changes === 1;
+}
+
+export async function updateDidSpecificSettings(
   accountDid: string,
   settingsChanges: Settings,
 ): Promise<boolean> {
@@ -241,6 +254,7 @@ export function generateInsertStatement(
   const values = Object.values(model).filter((value) => value !== undefined);
   const placeholders = values.map(() => "?").join(", ");
   const insertSql = `INSERT INTO ${tableName} (${columns.join(", ")}) VALUES (${placeholders})`;
+
   return {
     sql: insertSql,
     params: values,
diff --git a/src/libs/util.ts b/src/libs/util.ts
index cd3dfc5a..6f6133f0 100644
--- a/src/libs/util.ts
+++ b/src/libs/util.ts
@@ -44,6 +44,7 @@ import { logger } from "../utils/logger";
 import { PlatformServiceFactory } from "@/services/PlatformServiceFactory";
 import { sha256 } from "ethereum-cryptography/sha256";
 import { IIdentifier } from "@veramo/core";
+import { insertDidSpecificSettings } from "../db/databaseUtil";
 
 export interface GiverReceiverInputInfo {
   did?: string;
@@ -697,6 +698,7 @@ export async function saveNewIdentity(
     ];
     await platformService.dbExec(sql, params);
     await databaseUtil.updateDefaultSettings({ activeDid: identity.did });
+    await databaseUtil.insertDidSpecificSettings(identity.did);
 
     if (USE_DEXIE_DB) {
       // one of the few times we use accountsDBPromise directly; try to avoid more usage
@@ -710,6 +712,7 @@ export async function saveNewIdentity(
         publicKeyHex: identity.keys[0].publicKeyHex,
       });
       await updateDefaultSettings({ activeDid: identity.did });
+      await insertDidSpecificSettings(identity.did);
     }
   } catch (error) {
     logger.error("Failed to update default settings:", error);
@@ -732,7 +735,7 @@ export const generateSaveAndActivateIdentity = async (): Promise<string> => {
   const newId = newIdentifier(address, publicHex, privateHex, derivationPath);
 
   await saveNewIdentity(newId, mnemonic, derivationPath);
-  await databaseUtil.updateAccountSettings(newId.did, { isRegistered: false });
+  await databaseUtil.updateDidSpecificSettings(newId.did, { isRegistered: false });
   if (USE_DEXIE_DB) {
     await updateAccountSettings(newId.did, { isRegistered: false });
   }
@@ -774,7 +777,7 @@ export const registerSaveAndActivatePasskey = async (
 ): Promise<Account> => {
   const account = await registerAndSavePasskey(keyName);
   await databaseUtil.updateDefaultSettings({ activeDid: account.did });
-  await databaseUtil.updateAccountSettings(account.did, {
+  await databaseUtil.updateDidSpecificSettings(account.did, {
     isRegistered: false,
   });
   if (USE_DEXIE_DB) {
diff --git a/src/views/AccountViewView.vue b/src/views/AccountViewView.vue
index 874c7bbc..c3fee747 100644
--- a/src/views/AccountViewView.vue
+++ b/src/views/AccountViewView.vue
@@ -1814,7 +1814,7 @@ export default class AccountViewView extends Vue {
         if (!this.isRegistered) {
           // the user was not known to be registered, but now they are (because we got no error) so let's record it
           try {
-            await databaseUtil.updateAccountSettings(did, {
+            await databaseUtil.updateDidSpecificSettings(did, {
               isRegistered: true,
             });
             if (USE_DEXIE_DB) {
@@ -2018,7 +2018,7 @@ export default class AccountViewView extends Vue {
       if ((error as any).response.status === 404) {
         logger.error("The image was already deleted:", error);
 
-        await databaseUtil.updateAccountSettings(this.activeDid, {
+        await databaseUtil.updateDidSpecificSettings(this.activeDid, {
           profileImageUrl: undefined,
         });
         if (USE_DEXIE_DB) {
diff --git a/src/views/ContactsView.vue b/src/views/ContactsView.vue
index de94a41b..d45cf722 100644
--- a/src/views/ContactsView.vue
+++ b/src/views/ContactsView.vue
@@ -112,9 +112,9 @@
             Copy
           </button>
           <font-awesome
-            @click="showCopySelectionsInfo()"
             icon="circle-info"
             class="text-2xl text-blue-500 ml-2"
+            @click="showCopySelectionsInfo()"
           />
         </div>
       </div>
@@ -142,16 +142,13 @@
           class="text-md bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-3 py-1.5 rounded-md"
           @click="toggleShowContactAmounts()"
         >
-          {{
-            showGiveNumbers ? "Hide Actions" : "See Actions"
-          }}
+          {{ showGiveNumbers ? "Hide Actions" : "See Actions" }}
         </button>
       </div>
     </div>
     <div v-if="showGiveNumbers" class="my-3">
       <div class="w-full text-center text-sm italic text-slate-600">
-        Only the most recent hours are included. <br />To see more,
-        click
+        Only the most recent hours are included. <br />To see more, click
         <span
           class="text-sm uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1 py-0.5 rounded"
         >
@@ -223,9 +220,7 @@
                   />
                 </router-link>
 
-                <span class="text-xs truncate">{{
-                  contact.did
-                }}</span>
+                <span class="text-xs truncate">{{ contact.did }}</span>
               </div>
               <div class="text-sm">
                 {{ contact.notes }}
@@ -237,7 +232,7 @@
             v-if="showGiveNumbers && contact.did != activeDid"
             class="flex gap-1.5 items-end"
           >
-            <div class='text-center'>
+            <div class="text-center">
               <div class="text-xs leading-none mb-1">From/To</div>
               <div class="flex items-center">
                 <button
@@ -541,7 +536,7 @@ export default class ContactsView extends Vue {
         if (response.status != 201) {
           throw { error: { response: response } };
         }
-        await databaseUtil.updateAccountSettings(this.activeDid, {
+        await databaseUtil.updateDidSpecificSettings(this.activeDid, {
           isRegistered: true,
         });
         if (USE_DEXIE_DB) {
diff --git a/src/views/HelpView.vue b/src/views/HelpView.vue
index fe2aec3e..1e972f77 100644
--- a/src/views/HelpView.vue
+++ b/src/views/HelpView.vue
@@ -622,7 +622,7 @@ export default class HelpView extends Vue {
     }
 
     if (settings.activeDid) {
-      await databaseUtil.updateAccountSettings(settings.activeDid, {
+      await databaseUtil.updateDidSpecificSettings(settings.activeDid, {
         finishedOnboarding: false,
       });
       if (USE_DEXIE_DB) {
diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
index 0c69b60e..24ce8255 100644
--- a/src/views/HomeView.vue
+++ b/src/views/HomeView.vue
@@ -630,7 +630,7 @@ export default class HomeView extends Vue {
             this.activeDid,
           );
           if (resp.status === 200) {
-            await databaseUtil.updateAccountSettings(this.activeDid, {
+            await databaseUtil.updateDidSpecificSettings(this.activeDid, {
               isRegistered: true,
               ...(await databaseUtil.retrieveSettingsForActiveAccount()),
             });
@@ -785,7 +785,7 @@ export default class HomeView extends Vue {
           if (USE_DEXIE_DB) {
             settings = await retrieveSettingsForActiveAccount();
           }
-          await databaseUtil.updateAccountSettings(this.activeDid, {
+          await databaseUtil.updateDidSpecificSettings(this.activeDid, {
             apiServer: this.apiServer,
             isRegistered: true,
             ...settings,
diff --git a/src/views/ImportDerivedAccountView.vue b/src/views/ImportDerivedAccountView.vue
index 68fa4eb4..5e5ff232 100644
--- a/src/views/ImportDerivedAccountView.vue
+++ b/src/views/ImportDerivedAccountView.vue
@@ -79,7 +79,8 @@ import {
   newIdentifier,
   nextDerivationPath,
 } from "../libs/crypto";
-import { accountsDBPromise, db } from "../db/index";
+import * as databaseUtil from "../db/databaseUtil";
+import { db } from "../db/index";
 import { MASTER_SETTINGS_KEY } from "../db/tables/settings";
 import {
   retrieveAllAccountsMetadata,
@@ -164,23 +165,15 @@ export default class ImportAccountView extends Vue {
 
     try {
       await saveNewIdentity(newId, mne, newDerivPath);
-      if (USE_DEXIE_DB) {
-        const accountsDB = await accountsDBPromise;
-        await accountsDB.accounts.add({
-          dateCreated: new Date().toISOString(),
-          derivationPath: newDerivPath,
-          did: newId.did,
-          identity: JSON.stringify(newId),
-          mnemonic: mne,
-          publicKeyHex: newId.keys[0].publicKeyHex,
-        });
-      }
 
       // record that as the active DID
       const platformService = PlatformServiceFactory.getInstance();
       await platformService.dbExec("UPDATE settings SET activeDid = ?", [
         newId.did,
       ]);
+      await databaseUtil.updateDidSpecificSettings(newId.did, {
+        isRegistered: false,
+      });
       if (USE_DEXIE_DB) {
         await db.settings.update(MASTER_SETTINGS_KEY, {
           activeDid: newId.did,
diff --git a/src/views/NewActivityView.vue b/src/views/NewActivityView.vue
index 0becc1b5..b13a145a 100644
--- a/src/views/NewActivityView.vue
+++ b/src/views/NewActivityView.vue
@@ -257,7 +257,7 @@ export default class NewActivityView extends Vue {
   async expandOffersToUserAndMarkRead() {
     this.showOffersDetails = !this.showOffersDetails;
     if (this.showOffersDetails) {
-      await databaseUtil.updateAccountSettings(this.activeDid, {
+      await databaseUtil.updateDidSpecificSettings(this.activeDid, {
         lastAckedOfferToUserJwtId: this.newOffersToUser[0].jwtId,
       });
       if (USE_DEXIE_DB) {
@@ -285,7 +285,7 @@ export default class NewActivityView extends Vue {
     );
     if (index !== -1 && index < this.newOffersToUser.length - 1) {
       // Set to the next offer's jwtId
-      await databaseUtil.updateAccountSettings(this.activeDid, {
+      await databaseUtil.updateDidSpecificSettings(this.activeDid, {
         lastAckedOfferToUserJwtId: this.newOffersToUser[index + 1].jwtId,
       });
       if (USE_DEXIE_DB) {
@@ -295,7 +295,7 @@ export default class NewActivityView extends Vue {
       }
     } else {
       // it's the last entry (or not found), so just keep it the same
-      await databaseUtil.updateAccountSettings(this.activeDid, {
+      await databaseUtil.updateDidSpecificSettings(this.activeDid, {
         lastAckedOfferToUserJwtId: this.lastAckedOfferToUserJwtId,
       });
       if (USE_DEXIE_DB) {
@@ -319,7 +319,7 @@ export default class NewActivityView extends Vue {
     this.showOffersToUserProjectsDetails =
       !this.showOffersToUserProjectsDetails;
     if (this.showOffersToUserProjectsDetails) {
-      await databaseUtil.updateAccountSettings(this.activeDid, {
+      await databaseUtil.updateDidSpecificSettings(this.activeDid, {
         lastAckedOfferToUserProjectsJwtId:
           this.newOffersToUserProjects[0].jwtId,
       });
@@ -349,7 +349,7 @@ export default class NewActivityView extends Vue {
     );
     if (index !== -1 && index < this.newOffersToUserProjects.length - 1) {
       // Set to the next offer's jwtId
-      await databaseUtil.updateAccountSettings(this.activeDid, {
+      await databaseUtil.updateDidSpecificSettings(this.activeDid, {
         lastAckedOfferToUserProjectsJwtId:
           this.newOffersToUserProjects[index + 1].jwtId,
       });
@@ -361,7 +361,7 @@ export default class NewActivityView extends Vue {
       }
     } else {
       // it's the last entry (or not found), so just keep it the same
-      await databaseUtil.updateAccountSettings(this.activeDid, {
+      await databaseUtil.updateDidSpecificSettings(this.activeDid, {
         lastAckedOfferToUserProjectsJwtId:
           this.lastAckedOfferToUserProjectsJwtId,
       });