diff --git a/src/libs/endorserServer.ts b/src/libs/endorserServer.ts index 30bb7316..341a20f3 100644 --- a/src/libs/endorserServer.ts +++ b/src/libs/endorserServer.ts @@ -57,7 +57,7 @@ import { KeyMetaMaybeWithPrivate, } from "../interfaces/common"; import { PlanSummaryRecord } from "../interfaces/records"; -import { logger } from "../utils/logger"; +import { logger, safeStringify } from "../utils/logger"; import { PlatformServiceFactory } from "@/services/PlatformServiceFactory"; import { APP_SERVER } from "@/constants/app"; import { SOMEONE_UNNAMED } from "@/constants/entities"; @@ -685,7 +685,7 @@ export function serverMessageForUser(error: unknown): string | undefined { export function errorStringForLog(error: unknown) { let stringifiedError = "" + error; try { - stringifiedError = JSON.stringify(error); + stringifiedError = safeStringify(error); } catch (e) { // can happen with Dexie, eg: // TypeError: Converting circular structure to JSON @@ -697,7 +697,7 @@ export function errorStringForLog(error: unknown) { if (error && typeof error === "object" && "response" in error) { const err = error as AxiosErrorResponse; - const errorResponseText = JSON.stringify(err.response); + const errorResponseText = safeStringify(err.response); // for some reason, error.response is not included in stringify result (eg. for 400 errors on invite redemptions) if (!R.empty(errorResponseText) && !fullError.includes(errorResponseText)) { // add error.response stuff @@ -707,7 +707,7 @@ export function errorStringForLog(error: unknown) { R.equals(err.config, err.response.config) ) { // but exclude "config" because it's already in there - const newErrorResponseText = JSON.stringify( + const newErrorResponseText = safeStringify( R.omit(["config"] as never[], err.response), ); fullError += diff --git a/src/libs/util.ts b/src/libs/util.ts index 40d0fd3a..2c8c337b 100644 --- a/src/libs/util.ts +++ b/src/libs/util.ts @@ -988,11 +988,6 @@ export async function importFromMnemonic( ): Promise { const mne: string = mnemonic.trim().toLowerCase(); - // Check if this is Test User #0 - const TEST_USER_0_MNEMONIC = - "rigid shrug mobile smart veteran half all pond toilet brave review universe ship congress found yard skate elite apology jar uniform subway slender luggage"; - const isTestUser0 = mne === TEST_USER_0_MNEMONIC; - // Derive address and keys from mnemonic const [address, privateHex, publicHex] = deriveAddress(mne, derivationPath); @@ -1007,90 +1002,6 @@ export async function importFromMnemonic( // Save the new identity await saveNewIdentity(newId, mne, derivationPath); - - // Set up Test User #0 specific settings - if (isTestUser0) { - // Set up Test User #0 specific settings with enhanced error handling - const platformService = await getPlatformService(); - - try { - // First, ensure the DID-specific settings record exists - await platformService.insertNewDidIntoSettings(newId.did); - - // Then update with Test User #0 specific settings - await platformService.updateDidSpecificSettings(newId.did, { - firstName: "User Zero", - isRegistered: true, - }); - - // Verify the settings were saved correctly - const verificationResult = await platformService.dbQuery( - "SELECT firstName, isRegistered FROM settings WHERE accountDid = ?", - [newId.did], - ); - - if (verificationResult?.values?.length) { - const settings = verificationResult.values[0]; - const firstName = settings[0]; - const isRegistered = settings[1]; - - 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) { - logger.warn( - "[importFromMnemonic] Test User #0 settings not saved correctly, retrying with individual updates", - ); - - await platformService.dbExec( - "UPDATE settings SET firstName = ? WHERE accountDid = ?", - ["User Zero", newId.did], - ); - - await platformService.dbExec( - "UPDATE settings SET isRegistered = ? WHERE accountDid = ?", - [1, newId.did], - ); - - // Verify again - const retryResult = await platformService.dbQuery( - "SELECT firstName, isRegistered FROM settings WHERE accountDid = ?", - [newId.did], - ); - - if (retryResult?.values?.length) { - const retrySettings = retryResult.values[0]; - logger.debug( - "[importFromMnemonic] Test User #0 settings after retry", - { - firstName: retrySettings[0], - isRegistered: retrySettings[1], - }, - ); - } - } - } else { - logger.error( - "[importFromMnemonic] Failed to verify Test User #0 settings - no record found", - ); - } - } catch (error) { - logger.error( - "[importFromMnemonic] Error setting up Test User #0 settings:", - error, - ); - // Don't throw - allow the import to continue even if settings fail - } - } } /** diff --git a/src/services/platforms/CapacitorPlatformService.ts b/src/services/platforms/CapacitorPlatformService.ts index 2db74656..b1907f13 100644 --- a/src/services/platforms/CapacitorPlatformService.ts +++ b/src/services/platforms/CapacitorPlatformService.ts @@ -1343,10 +1343,21 @@ export class CapacitorPlatformService implements PlatformService { async updateDefaultSettings( settings: Record, ): Promise { + // Get current active DID and update that identity's settings + const activeIdentity = await this.getActiveIdentity(); + const activeDid = activeIdentity.activeDid; + + if (!activeDid) { + logger.warn( + "[CapacitorPlatformService] No active DID found, cannot update default settings", + ); + return; + } + const keys = Object.keys(settings); const setClause = keys.map((key) => `${key} = ?`).join(", "); - const sql = `UPDATE settings SET ${setClause} WHERE id = 1`; - const params = keys.map((key) => settings[key]); + const sql = `UPDATE settings SET ${setClause} WHERE accountDid = ?`; + const params = [...keys.map((key) => settings[key]), activeDid]; await this.dbExec(sql, params); } @@ -1357,6 +1368,15 @@ export class CapacitorPlatformService implements PlatformService { ); } + async getActiveIdentity(): Promise<{ activeDid: string }> { + const result = await this.dbQuery( + "SELECT activeDid FROM active_identity WHERE id = 1", + ); + return { + activeDid: (result?.values?.[0]?.[0] as string) || "", + }; + } + async insertNewDidIntoSettings(did: string): Promise { // Import constants dynamically to avoid circular dependencies const { DEFAULT_ENDORSER_API_SERVER, DEFAULT_PARTNER_API_SERVER } = @@ -1385,7 +1405,18 @@ export class CapacitorPlatformService implements PlatformService { string, unknown > | null> { - const result = await this.dbQuery("SELECT * FROM settings WHERE id = 1"); + // Get current active DID from active_identity table + const activeIdentity = await this.getActiveIdentity(); + const activeDid = activeIdentity.activeDid; + + if (!activeDid) { + return null; + } + + const result = await this.dbQuery( + "SELECT * FROM settings WHERE accountDid = ?", + [activeDid], + ); if (result?.values?.[0]) { // Convert the row to an object const row = result.values[0]; diff --git a/src/services/platforms/WebPlatformService.ts b/src/services/platforms/WebPlatformService.ts index 3d8248f5..f5edcc28 100644 --- a/src/services/platforms/WebPlatformService.ts +++ b/src/services/platforms/WebPlatformService.ts @@ -753,7 +753,18 @@ export class WebPlatformService implements PlatformService { string, unknown > | null> { - const result = await this.dbQuery("SELECT * FROM settings WHERE id = 1"); + // Get current active DID from active_identity table + const activeIdentity = await this.getActiveIdentity(); + const activeDid = activeIdentity.activeDid; + + if (!activeDid) { + return null; + } + + const result = await this.dbQuery( + "SELECT * FROM settings WHERE accountDid = ?", + [activeDid], + ); if (result?.values?.[0]) { // Convert the row to an object const row = result.values[0]; diff --git a/src/views/AccountViewView.vue b/src/views/AccountViewView.vue index 740eb418..cd0cd25e 100644 --- a/src/views/AccountViewView.vue +++ b/src/views/AccountViewView.vue @@ -1064,6 +1064,53 @@ export default class AccountViewView extends Vue { this.hideRegisterPromptOnNewContact = !!settings.hideRegisterPromptOnNewContact; this.isRegistered = !!settings?.isRegistered; + + // If settings show unregistered but user has activeDid, verify registration status + if (!this.isRegistered && this.activeDid) { + logger.debug( + "[AccountViewView] Settings show unregistered, verifying with server:", + { + activeDid: this.activeDid, + apiServer: this.apiServer, + }, + ); + + try { + const { fetchEndorserRateLimits } = await import( + "@/libs/endorserServer" + ); + const resp = await fetchEndorserRateLimits( + this.apiServer, + this.axios, + this.activeDid, + ); + + if (resp.status === 200) { + logger.debug( + "[AccountViewView] Server confirms user IS registered, updating settings:", + { + activeDid: this.activeDid, + wasRegistered: false, + nowRegistered: true, + }, + ); + + // Update settings and state + await this.$saveUserSettings(this.activeDid, { + isRegistered: true, + }); + this.isRegistered = true; + } + } catch (error) { + logger.debug( + "[AccountViewView] Registration check failed (expected for unregistered users):", + { + activeDid: this.activeDid, + error: error instanceof Error ? error.message : String(error), + }, + ); + } + } this.isSearchAreasSet = !!settings.searchBoxes; this.searchBox = settings.searchBoxes?.[0] || null; this.notifyingNewActivity = !!settings.notifyingNewActivityTime; @@ -1479,18 +1526,21 @@ export default class AccountViewView extends Vue { status?: number; }; }; - logger.error("[Server Limits] Error retrieving limits:", { - error: error instanceof Error ? error.message : String(error), - did: did, - apiServer: this.apiServer, - imageServer: this.DEFAULT_IMAGE_API_SERVER, - partnerApiServer: this.partnerApiServer, - errorCode: axiosError?.response?.data?.error?.code, - errorMessage: axiosError?.response?.data?.error?.message, - httpStatus: axiosError?.response?.status, - needsUserMigration: true, - timestamp: new Date().toISOString(), - }); + logger.warn( + "[Server Limits] Error retrieving limits, expected for unregistered users:", + { + error: error instanceof Error ? error.message : String(error), + did: did, + apiServer: this.apiServer, + imageServer: this.DEFAULT_IMAGE_API_SERVER, + partnerApiServer: this.partnerApiServer, + errorCode: axiosError?.response?.data?.error?.code, + errorMessage: axiosError?.response?.data?.error?.message, + httpStatus: axiosError?.response?.status, + needsUserMigration: true, + timestamp: new Date().toISOString(), + }, + ); // this.notify.error(this.limitsMessage, TIMEOUTS.STANDARD); } finally { diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue index e8d2035a..2c51fb84 100644 --- a/src/views/HomeView.vue +++ b/src/views/HomeView.vue @@ -662,7 +662,7 @@ export default class HomeView extends Vue { }; logger.warn( - "[HomeView Settings Trace] ⚠️ Registration check failed", + "[HomeView Settings Trace] ⚠️ Registration check failed, expected for unregistered users.", { error: errorMessage, did: this.activeDid,